aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog180
-rw-r--r--gcc/cp/call.c39
-rw-r--r--gcc/cp/class.c18
-rw-r--r--gcc/cp/cp-tree.h23
-rw-r--r--gcc/cp/cvt.c173
-rw-r--r--gcc/cp/decl.c141
-rw-r--r--gcc/cp/decl2.c7
-rw-r--r--gcc/cp/except.c22
-rw-r--r--gcc/cp/gxx.gperf5
-rw-r--r--gcc/cp/hash.h170
-rw-r--r--gcc/cp/init.c7
-rw-r--r--gcc/cp/lex.c3
-rw-r--r--gcc/cp/lex.h1
-rw-r--r--gcc/cp/parse.y115
-rw-r--r--gcc/cp/pt.c43
-rw-r--r--gcc/cp/search.c2
-rw-r--r--gcc/cp/tree.c3
-rw-r--r--gcc/cp/typeck.c94
-rw-r--r--gcc/cp/typeck2.c9
19 files changed, 670 insertions, 385 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4b3b09d..bd2be26 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
+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)
Add alpha exception handling support to the compiler.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8f8bac2..6700f87 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2672,7 +2672,7 @@ build_scoped_method_call (exp, scopes, name, parms)
}
/* 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);
}
return error_mark_node;
@@ -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
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)
{
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)
TYPE_ARG_TYPES (TREE_TYPE (function)),
parms, &template_cost, 0);
if (i == 0)
- {
- 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;
- }
+ function = instantiate_template (function, targs);
}
if (TREE_CODE (function) == TEMPLATE_DECL)
@@ -4076,6 +4068,19 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
}
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);
/* Can't use alloca here, since result might be
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 730d0ca..27e9a4b 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2734,10 +2734,22 @@ finish_struct (t, list_of_fieldlists, warn_anon)
if (TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL)
{
tree name = DECL_NAME (x);
- tree icv = name ? IDENTIFIER_CLASS_VALUE (name) : NULL_TREE;
+ tree icv;
- /* Don't complain about constructors. */
- if (icv && name != constructor_name (current_class_type))
+ /* Don't get confused by access decls. */
+ 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'",
name, x);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 54dc2b2..5d7cfa7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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_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_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE || t == UNINSTANTIATED_P_TYPE)
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
@@ -1723,6 +1726,24 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
#define LOOKUP_NO_CONVERSION (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):
purpose = friend name (IDENTIFIER_NODE);
value = TREE_LIST of FUNCTION_DECLS;
@@ -1790,7 +1811,7 @@ extern void print_class_statistics PROTO((void));
extern void maybe_push_cache_obstack PROTO((void));
/* 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_to_aggr PROTO((tree, tree, char **, int));
extern tree convert_pointer_to PROTO((tree, tree));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index b160412..d614c70 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -594,40 +594,29 @@ build_up_reference (type, arg, flags, checkconst)
/* For C++: Only need to do one-level references, but cannot
get tripped up on signed/unsigned differences.
- If DECL is NULL_TREE it means convert as though casting (by force).
- If it is ERROR_MARK_NODE, it means the conversion is implicit,
- and that temporaries may be created.
- Make sure the use of user-defined conversion operators is un-ambiguous.
- Otherwise, DECL is a _DECL node which can be used in error reporting.
+ DECL is either NULL_TREE or the _DECL node for a reference that is being
+ initialized. It can be error_mark_node if we don't know the _DECL but
+ we know it's an initialization. */
- FNDECL, PARMNUM, and ERRTYPE are only used when checking for use of
- volatile or const references where they aren't desired. */
+tree cp_convert PROTO((tree, tree, int, int));
tree
-convert_to_reference (decl, reftype, expr, fndecl, parmnum,
- errtype, strict, flags)
- tree decl;
+convert_to_reference (reftype, expr, convtype, flags, decl)
tree reftype, expr;
- tree fndecl;
- int parmnum;
- char *errtype;
- int strict, flags;
+ int convtype, flags;
+ tree decl;
{
register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
register tree intype = TREE_TYPE (expr);
register enum tree_code form = TREE_CODE (intype);
tree rval = NULL_TREE;
-#if 0
- if (TREE_CODE (type) == ARRAY_TYPE)
- type = build_pointer_type (TREE_TYPE (type));
-#endif
-
if (form == REFERENCE_TYPE)
intype = TREE_TYPE (intype);
intype = TYPE_MAIN_VARIANT (intype);
if (IS_AGGR_TYPE (intype)
+ && ! (flags & LOOKUP_NO_CONVERSION)
&& (rval = build_type_conversion (CONVERT_EXPR, reftype, expr, 1)))
{
if (rval == error_mark_node)
@@ -636,16 +625,11 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
return rval;
}
- if (comptypes (type, intype, strict))
+ if (((convtype & CONV_STATIC) && comptypes (type, intype, -1))
+ || ((convtype & CONV_IMPLICIT) && comptypes (type, intype, 0)))
{
- /* Section 13. */
if (flags & LOOKUP_COMPLAIN)
{
- /* Since convert_for_initialization didn't call
- convert_for_assignment, we have to do this checking here.
- FIXME: We should have a common routine between here and
- convert_for_assignment. */
-
tree ttl = TREE_TYPE (reftype);
tree ttr;
@@ -654,37 +638,25 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
else
ttr = TREE_TYPE (expr);
- if (! TYPE_READONLY (ttl))
+ if (! lvalue_p (expr) &&
+ (decl == NULL_TREE || ! TYPE_READONLY (ttl)))
{
- if (TYPE_READONLY (ttr) && decl != NULL_TREE)
- {
- if (fndecl)
- cp_pedwarn ("passing `%T' as argument %P of `%D' discards const",
- TREE_TYPE (expr), parmnum, fndecl);
- else
- cp_pedwarn ("%s to `%T' from `%T' discards const",
- errtype, reftype, TREE_TYPE (expr));
- }
- else if (! lvalue_p (expr))
- {
- /* Ensure semantics of 8.4.3 */
- if (fndecl)
- cp_pedwarn ("ANSI C++ forbids passing non-lvalue `%T' as argument %P of `%D' into non-const &",
- TREE_TYPE (expr), parmnum, fndecl);
- else
- cp_pedwarn ("ANSI C++ forbids %s to `%T' from non-lvalue `%T'",
- errtype, reftype, TREE_TYPE (expr));
- }
+ if (decl)
+ /* Ensure semantics of [dcl.init.ref] */
+ cp_pedwarn ("initialization of non-const `%T' from rvalue `%T'",
+ reftype, intype);
+ else
+ cp_pedwarn ("conversion to `%T' from rvalue `%T'",
+ reftype, intype);
}
- else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)
- && decl != NULL_TREE)
+ else if (! (convtype & CONV_CONST))
{
- if (fndecl)
- cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile",
- TREE_TYPE (expr), parmnum, fndecl);
- else
- cp_pedwarn ("%s to `%T' from `%T' discards volatile",
- errtype, reftype, TREE_TYPE (expr));
+ if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
+ cp_pedwarn ("conversion from `%T' to `%T' discards const",
+ TREE_TYPE (expr), reftype);
+ else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
+ cp_pedwarn ("conversion from `%T' to `%T' discards volatile",
+ TREE_TYPE (expr), reftype);
}
}
@@ -718,15 +690,17 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
rval = build1 (NOP_EXPR,
build_pointer_type (TREE_TYPE (TREE_TYPE (expr))),
expr);
- rval = convert (build_pointer_type (TREE_TYPE (reftype)), rval);
+ rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), rval,
+ convtype, flags);
rval = build1 (NOP_EXPR, reftype, rval);
return rval;
}
- return build_up_reference (reftype, expr, flags, decl!=NULL_TREE);
+ return build_up_reference (reftype, expr, flags,
+ ! (convtype & CONV_CONST));
}
- if (decl == NULL_TREE && lvalue_p (expr))
+ if ((convtype & CONV_REINTERPRET) && lvalue_p (expr))
{
/* When casting an lvalue to a reference type, just convert into
a pointer to the new type and deference it. This is allowed
@@ -736,7 +710,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
/* B* bp; A& ar = (A&)bp; is legal, but it's probably not what they
meant. */
if (form == POINTER_TYPE
- && (comptypes (TREE_TYPE (intype), type, strict)))
+ && (comptypes (TREE_TYPE (intype), type, -1)))
cp_warning ("casting `%T' to `%T' does not dereference pointer",
intype, reftype);
@@ -746,7 +720,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
if (rval != error_mark_node)
rval = build1 (NOP_EXPR, reftype, rval);
}
- else if (decl == error_mark_node || decl == NULL_TREE)
+ else if (decl)
{
tree rval_as_conversion = NULL_TREE;
tree rval_as_ctor = NULL_TREE;
@@ -773,23 +747,25 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
if (global_bindings_p ())
{
extern tree static_aggregates;
- decl = get_temp_name (type, global_bindings_p ());
- init = build_method_call (decl, constructor_name_full (type),
+ tree t = get_temp_name (type, global_bindings_p ());
+ init = build_method_call (t, constructor_name_full (type),
build_tree_list (NULL_TREE, expr),
- TYPE_BINFO (type), LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
+ TYPE_BINFO (type),
+ LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
if (init == error_mark_node)
return error_mark_node;
- make_decl_rtl (decl, NULL_PTR, 1);
- static_aggregates = perm_tree_cons (expr, decl, static_aggregates);
- rval = build_unary_op (ADDR_EXPR, decl, 0);
+ make_decl_rtl (t, NULL_PTR, 1);
+ static_aggregates = perm_tree_cons (expr, t, static_aggregates);
+ rval = build_unary_op (ADDR_EXPR, t, 0);
}
else
{
init = build_method_call (NULL_TREE, constructor_name_full (type),
build_tree_list (NULL_TREE, expr),
- TYPE_BINFO (type), LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
+ TYPE_BINFO (type),
+ LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
if (init == error_mark_node)
return error_mark_node;
@@ -820,8 +796,8 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
}
if (rval && ! TYPE_READONLY (TREE_TYPE (reftype)))
- cp_pedwarn ("converting `%T' to non-const `%T' will use a temporary",
- intype, reftype);
+ cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary",
+ reftype, intype);
}
if (rval)
@@ -1219,15 +1195,10 @@ convert_pointer_to_vbase (binfo, expr)
return NULL_TREE;
}
-/* Create an expression whose value is that of EXPR,
- converted to type TYPE. The TREE_TYPE of the value
- is always TYPE. This function implements all reasonable
- conversions; callers should filter out those that are
- not permitted by the language being compiled. */
-
tree
-convert (type, expr)
+cp_convert (type, expr, convtype, flags)
tree type, expr;
+ int convtype, flags;
{
register tree e = expr;
register enum tree_code code = TREE_CODE (type);
@@ -1235,25 +1206,16 @@ convert (type, expr)
if (type == TREE_TYPE (expr)
|| TREE_CODE (expr) == ERROR_MARK)
return expr;
- if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
- return fold (build1 (NOP_EXPR, type, expr));
if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
return error_mark_node;
- if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
- {
- error ("void value not ignored as it ought to be");
- return error_mark_node;
- }
- if (code == VOID_TYPE)
- {
- /* We're converting to a void type; see if they have an
- `operator void'. */
- tree rval = build_type_conversion (NOP_EXPR, type, e, 0);
- /* If we can convert to void type via a type conversion, do so. */
- if (rval)
- return rval;
- return build1 (CONVERT_EXPR, type, e);
- }
+
+ /* Trivial conversion: cv-qualifiers do not matter on rvalues. */
+ if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
+ return fold (build1 (NOP_EXPR, type, expr));
+
+ if (code == VOID_TYPE && (convtype & CONV_STATIC))
+ return build1 (CONVERT_EXPR, type, e);
+
#if 0
/* This is incorrect. A truncation can't be stripped this way.
Extensions will be stripped by the use of get_unwidened. */
@@ -1268,10 +1230,8 @@ convert (type, expr)
code = TREE_CODE (type);
}
- /* C++ */
if (code == REFERENCE_TYPE)
- return fold (convert_to_reference (error_mark_node, type, e, NULL_TREE,
- -1, "conversion", -1, LOOKUP_NORMAL));
+ return fold (convert_to_reference (type, e, convtype, flags, NULL_TREE));
else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
e = convert_from_reference (e);
@@ -1455,6 +1415,19 @@ convert (type, expr)
return error_mark_node;
}
+/* Create an expression whose value is that of EXPR,
+ converted to type TYPE. The TREE_TYPE of the value
+ is always TYPE. This function implements all reasonable
+ conversions; callers should filter out those that are
+ not permitted by the language being compiled. */
+
+tree
+convert (type, expr)
+ tree type, expr;
+{
+ return cp_convert (type, expr, CONV_OLD_CONVERT, 0);
+}
+
/* Like convert, except permit conversions to take place which
are not normally allowed due to access restrictions
(such as conversion from sub-type to private super-type). */
@@ -1467,8 +1440,8 @@ convert_force (type, expr)
register enum tree_code code = TREE_CODE (type);
if (code == REFERENCE_TYPE)
- return fold (convert_to_reference (0, type, e, NULL_TREE, -1,
- "casting", -1, LOOKUP_COMPLAIN));
+ return fold (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN,
+ NULL_TREE));
else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
e = convert_from_reference (e);
@@ -1539,11 +1512,7 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
&& (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval)))
> TREE_READONLY (TREE_TYPE (xtype))))
warning ("user-defined conversion casting away `const'");
- rval = convert_for_initialization (NULL_TREE, xtype, rval, flags,
- "conversion", NULL_TREE, 0);
- if (rval == error_mark_node)
- return NULL_TREE;
- return rval;
+ return convert (xtype, rval);
}
/* Convert an aggregate EXPR to type XTYPE. If a conversion
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e33db79..1c9905f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -47,6 +47,8 @@ extern struct obstack permanent_obstack;
extern int current_class_depth;
+extern tree cleanups_this_call;
+
/* Stack of places to restore the search obstack back to. */
/* Obstack used for remembering local class declarations (like
@@ -1077,7 +1079,7 @@ poplevel (keep, reverse, functionbody)
}
/* Take care of compiler's internal binding structures. */
- if (tmp == 2 && class_binding_level)
+ if (tmp == 2)
{
#if 0
/* We did not call push_momentary for this
@@ -1976,7 +1978,7 @@ decls_match (newdecl, olddecl)
TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
}
else
- types_match = compparms (p1, p2, 1);
+ types_match = compparms (p1, p2, 3);
}
else
types_match = 0;
@@ -2114,31 +2116,44 @@ duplicate_decls (newdecl, olddecl)
after implicit decl. */
;
else if (TREE_CODE (olddecl) == FUNCTION_DECL
- && (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. */
+ && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)))
{
/* If you declare a built-in or predefined function name as static,
- the old definition is overridden,
- but optionally warn this was a bad choice of name. */
- if (! TREE_PUBLIC (newdecl))
- if (warn_shadow)
- cp_warning ("shadowing %s function `%#D'",
- DECL_BUILT_IN (olddecl) ? "built-in" : "library",
- newdecl);
- /* Likewise, if the built-in is not ansi, then programs can override
- it even globally without an error. */
- else if (! DECL_BUILT_IN (olddecl))
- cp_warning ("library function `%#D' redeclared as non-function `%#D'",
- olddecl, newdecl);
- else
+ the old definition is overridden, but optionally warn this was a
+ bad choice of name. Ditto for overloads. */
+ if (! TREE_PUBLIC (newdecl)
+ || (TREE_CODE (newdecl) == FUNCTION_DECL
+ && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)))
+ {
+ if (warn_shadow)
+ cp_warning ("shadowing %s function `%#D'",
+ DECL_BUILT_IN (olddecl) ? "built-in" : "library",
+ olddecl);
+ /* Discard the old built-in function. */
+ return 0;
+ }
+ 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 ("conflicts with built-in declaration `%#D'",
olddecl);
}
- return 0;
}
else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
{
@@ -2185,7 +2200,7 @@ duplicate_decls (newdecl, olddecl)
}
/* 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)
{
/* Since we're doing this before finish_struct can set the
@@ -3082,7 +3097,12 @@ pushdecl_class_level (x)
members are checked in finish_struct. */
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_at ("conflicts with previous use in class as `%#D'",
@@ -3186,23 +3206,18 @@ push_overloaded_decl (decl, forgettable)
{
old = IDENTIFIER_GLOBAL_VALUE (orig_name);
if (old && TREE_CODE (old) == FUNCTION_DECL
+ && DECL_ARTIFICIAL (old)
&& (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old)))
{
- if (! decls_match (decl, old)
- && (DECL_LANGUAGE (decl) == lang_c
- || 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);
- }
+ if (duplicate_decls (decl, old))
+ return old;
old = NULL_TREE;
}
}
else
{
old = IDENTIFIER_LOCAL_VALUE (orig_name);
-
+
if (! purpose_member (orig_name, current_binding_level->shadowed))
{
current_binding_level->shadowed
@@ -3355,6 +3370,18 @@ redeclaration_error_message (newdecl, olddecl)
else
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;
}
else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
@@ -3990,9 +4017,19 @@ lookup_name_current_level (name)
}
else if (IDENTIFIER_LOCAL_VALUE (name) != NULL_TREE)
{
- for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
- if (DECL_NAME (t) == name)
- break;
+ struct binding_level *b = current_binding_level;
+ while (1)
+ {
+ 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;
@@ -5559,25 +5596,14 @@ grok_reference_init (decl, type, init, cleanupp)
}
/* OK, can we generate a reference then? */
else if ((actual_init = convert_to_reference
- (decl, type, init, 0, 0, "initialization", 0,
- LOOKUP_SPECULATIVELY|LOOKUP_NORMAL)))
+ (type, init, CONV_IMPLICIT,
+ LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl)))
{
if (actual_init == error_mark_node)
goto fail;
init = actual_init;
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)
{
@@ -5705,12 +5731,9 @@ finish_decl (decl, init, asmspec_tree, need_pop)
return;
}
+ /* If a name was specified, get the string. */
if (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
a constructor, or has a virtual function table pointer,
@@ -6276,6 +6299,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
}
else if (! toplev)
{
+ tree old_cleanups = cleanups_this_call;
/* This is a declared decl which must live until the
end of the binding contour. It may need a cleanup. */
@@ -6335,6 +6359,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
decl);
}
}
+ /* Cleanup any temporaries needed for the initial value. */
+ expand_cleanups_to (old_cleanups);
}
finish_end0:
@@ -6404,6 +6430,8 @@ expand_static_init (decl, init)
tree init;
{
tree oldstatic = value_member (decl, static_aggregates);
+ tree old_cleanups;
+
if (oldstatic)
{
if (TREE_PURPOSE (oldstatic) && init != NULL_TREE)
@@ -6422,6 +6450,7 @@ expand_static_init (decl, init)
rest_of_decl_compilation (temp, NULL_PTR, 0, 0);
expand_start_cond (build_binary_op (EQ_EXPR, temp,
integer_zero_node, 1), 0);
+ old_cleanups = cleanups_this_call;
expand_assignment (temp, integer_one_node, 0, 0);
if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
{
@@ -6430,6 +6459,8 @@ expand_static_init (decl, init)
}
else
expand_assignment (decl, init, 0, 0);
+ /* Cleanup any temporaries needed for the initial value. */
+ expand_cleanups_to (old_cleanups);
expand_end_cond ();
if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
{
@@ -10235,6 +10266,7 @@ finish_enum (enumtype, values)
else if (value < minvalue)
minvalue = value;
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)
if (argtypes)
*argtypes = args;
}
+
+int
+id_in_current_class (id)
+ tree id;
+{
+ return !!purpose_member (id, class_binding_level->class_shadowed);
+}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index d6eb5d9..c5ab8db 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -37,6 +37,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
extern tree grokdeclarator ();
extern tree get_file_function_name ();
+extern tree cleanups_this_call;
static void grok_function_init ();
/* 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[] =
{"huge-objects", &flag_huge_objects, 1},
{"conserve-space", &flag_conserve_space, 1},
{"vtable-thunks", &flag_vtable_thunks, 1},
+ {"short-temps", &flag_short_temps, 1},
};
/* Decode the string P as a language-specific option.
@@ -2595,6 +2597,7 @@ finish_file ()
{
tree decl = TREE_VALUE (vars);
tree init = TREE_PURPOSE (vars);
+ tree old_cleanups = cleanups_this_call;
/* If this was a static attribute within some function's scope,
then don't initialize it here. Also, don't bother
@@ -2684,6 +2687,8 @@ finish_file ()
;
else my_friendly_abort (22);
vars = TREE_CHAIN (vars);
+ /* Cleanup any temporaries needed for the initial value. */
+ expand_cleanups_to (old_cleanups);
}
expand_end_bindings (getdecls(), 1, 0);
@@ -2936,7 +2941,7 @@ finish_decl_parsing (decl)
TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
return decl;
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;
return decl;
case ARRAY_REF:
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 60fd392..160a10b 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -35,11 +35,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
tree builtin_return_address_fndecl;
/* Define at your own risk! */
+#ifndef CROSS_COMPILE
#ifdef sun
#ifdef sparc
#define TRY_NEW_EH
#endif
#endif
+#endif
#ifndef TRY_NEW_EH
@@ -97,8 +99,8 @@ expand_end_all_catch ()
}
void
-expand_start_catch_block (typename, identifier)
- tree typename, identifier;
+expand_start_catch_block (declspecs, declarator)
+ tree declspecs, declarator;
{
}
@@ -409,7 +411,6 @@ exception_section ()
extern rtx emit_insn PROTO((rtx));
extern rtx gen_nop PROTO(());
-extern void do_unwind PROTO((rtx));
/* local globals for function calls
====================================================================== */
@@ -808,7 +809,7 @@ init_exception_processing ()
catch_match_fndecl =
define_function ("__throw_type_match",
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,
pushdecl,
0);
@@ -1088,24 +1089,27 @@ expand_leftover_cleanups ()
}
}
-
/* 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
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.
(ie: it ends up as the "else" clause rather than an "else if" clause) */
void
-expand_start_catch_block (typename, identifier)
- tree typename, identifier;
+expand_start_catch_block (declspecs, declarator)
+ tree declspecs, declarator;
{
rtx false_label_rtx;
tree type;
+ tree decl;
if (! doing_eh (1))
return;
- if (typename)
- type = groktypename (typename);
+ if (declspecs)
+ {
+ decl = grokdeclarator (declarator, declspecs, PARM, 0, NULL_TREE);
+ type = TREE_TYPE (decl);
+ }
else
type = NULL_TREE;
diff --git a/gcc/cp/gxx.gperf b/gcc/cp/gxx.gperf
index 33f1d23..a358534 100644
--- a/gcc/cp/gxx.gperf
+++ b/gcc/cp/gxx.gperf
@@ -35,6 +35,7 @@ char, TYPESPEC, RID_CHAR,
class, AGGR, RID_CLASS,
classof, CLASSOF, NORID,
const, TYPE_QUAL, RID_CONST,
+const_cast, CONST_CAST, NORID,
continue, CONTINUE, NORID,
default, DEFAULT, NORID,
delete, DELETE, NORID,
@@ -61,6 +62,7 @@ private, VISSPEC, RID_PRIVATE,
protected, VISSPEC, RID_PROTECTED,
public, VISSPEC, RID_PUBLIC,
register, SCSPEC, RID_REGISTER,
+reinterpret_cast, REINTERPRET_CAST, NORID,
return, RETURN, NORID,
short, TYPESPEC, RID_SHORT,
signature, AGGR, RID_SIGNATURE /* Extension */,
@@ -68,11 +70,12 @@ signed, TYPESPEC, RID_SIGNED,
sigof, SIGOF, NORID /* Extension */,
sizeof, SIZEOF, NORID,
static, SCSPEC, RID_STATIC,
+static_cast, STATIC_CAST, NORID,
struct, AGGR, RID_RECORD,
switch, SWITCH, NORID,
this, THIS, NORID,
throw, THROW, NORID,
-template, TEMPLATE, NORID,
+template, TEMPLATE, RID_TEMPLATE,
try, TRY, NORID,
typedef, SCSPEC, RID_TYPEDEF,
typeof, TYPEOF, NORID,
diff --git a/gcc/cp/hash.h b/gcc/cp/hash.h
index 86bc4ca..0780d02 100644
--- a/gcc/cp/hash.h
+++ b/gcc/cp/hash.h
@@ -1,14 +1,14 @@
/* 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 */
struct resword { char *name; short token; enum rid rid;};
-#define TOTAL_KEYWORDS 80
+#define TOTAL_KEYWORDS 83
#define MIN_WORD_LENGTH 2
-#define MAX_WORD_LENGTH 13
+#define MAX_WORD_LENGTH 16
#define MIN_HASH_VALUE 4
-#define MAX_HASH_VALUE 166
-/* maximum key range = 163, duplicates = 0 */
+#define MAX_HASH_VALUE 170
+/* maximum key range = 167, duplicates = 0 */
#ifdef __GNUC__
inline
@@ -20,19 +20,19 @@ hash (str, len)
{
static unsigned char asso_values[] =
{
- 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 0, 167, 36, 6, 60,
- 17, 0, 16, 5, 41, 38, 167, 11, 22, 7,
- 26, 0, 4, 167, 22, 0, 4, 44, 19, 8,
- 5, 18, 167, 167, 167, 167, 167, 167,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 171, 171, 171, 171, 0, 171, 62, 5, 65,
+ 27, 0, 18, 7, 10, 48, 171, 1, 30, 7,
+ 79, 0, 33, 171, 18, 0, 4, 26, 13, 0,
+ 1, 24, 171, 171, 171, 171, 171, 171,
};
register int hval = len;
@@ -68,103 +68,117 @@ is_reserved_word (str, len)
{"",}, {"",},
{"__asm__", GCC_ASM_KEYWORD, NORID},
{"this", THIS, NORID,},
- {"goto", GOTO, NORID,},
+ {"throw", THROW, NORID,},
{"__headof__", HEADOF, NORID},
- {"",},
+ {"goto", GOTO, NORID,},
{"__asm", GCC_ASM_KEYWORD, NORID},
{"__const__", TYPE_QUAL, RID_CONST},
{"__volatile", TYPE_QUAL, RID_VOLATILE},
{"__const", TYPE_QUAL, RID_CONST},
{"__volatile__", TYPE_QUAL, RID_VOLATILE},
- {"throw", THROW, NORID,},
+ {"",},
{"enum", ENUM, NORID,},
- {"do", DO, NORID,},
- {"template", TEMPLATE, NORID,},
+ {"static_cast", STATIC_CAST, NORID,},
+ {"switch", SWITCH, NORID,},
+ {"",}, {"",},
{"sigof", SIGOF, NORID /* Extension */,},
{"sizeof", SIZEOF, NORID,},
- {"delete", DELETE, NORID,},
+ {"",},
{"__headof", HEADOF, NORID},
- {"try", TRY, NORID,},
+ {"short", TYPESPEC, RID_SHORT,},
{"typeof", TYPEOF, NORID,},
- {"typeid", TYPEID, NORID,},
+ {"do", DO, NORID,},
+ {"",},
+ {"try", TRY, NORID,},
+ {"",},
+ {"delete", DELETE, NORID,},
{"__typeof__", TYPEOF, NORID},
+ {"while", WHILE, NORID,},
+ {"struct", AGGR, RID_RECORD,},
+ {"typeid", TYPEID, NORID,},
{"double", TYPESPEC, RID_DOUBLE,},
- {"private", VISSPEC, RID_PRIVATE,},
- {"short", TYPESPEC, RID_SHORT,},
- {"extern", SCSPEC, RID_EXTERN,},
- {"__classof__", CLASSOF, NORID},
+ {"for", FOR, NORID,},
{"",},
- {"while", WHILE, NORID,},
+ {"__classof__", CLASSOF, NORID},
+ {"",}, {"",},
+ {"operator", OPERATOR, NORID,},
+ {"",}, {"",},
+ {"typedef", SCSPEC, RID_TYPEDEF,},
{"long", TYPESPEC, RID_LONG,},
- {"new", NEW, NORID,},
- {"protected", VISSPEC, RID_PROTECTED,},
- {"friend", SCSPEC, RID_FRIEND,},
- {"auto", SCSPEC, RID_AUTO,},
- {"for", FOR, NORID,},
+ {"template", TEMPLATE, RID_TEMPLATE,},
{"__typeof", TYPEOF, NORID},
- {"typedef", SCSPEC, RID_TYPEDEF,},
- {"__extension__", EXTENSION, NORID},
+ {"friend", SCSPEC, RID_FRIEND,},
+ {"",},
+ {"private", VISSPEC, RID_PRIVATE,},
+ {"",},
{"int", TYPESPEC, RID_INT,},
- {"asm", ASM_KEYWORD, NORID,},
+ {"",},
{"__classof", CLASSOF, NORID},
{"__signed__", TYPESPEC, RID_SIGNED},
- {"signed", TYPESPEC, RID_SIGNED,},
- {"mutable", SCSPEC, RID_MUTABLE,},
- {"switch", SWITCH, NORID,},
- {"operator", OPERATOR, NORID,},
+ {"",}, {"",},
+ {"headof", HEADOF, NORID,},
+ {"",},
{"__attribute", ATTRIBUTE, NORID},
- {"struct", AGGR, RID_RECORD,},
+ {"",},
{"__attribute__", ATTRIBUTE, NORID},
+ {"auto", SCSPEC, RID_AUTO,},
+ {"",},
{"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,},
{"class", AGGR, RID_CLASS,},
- {"",},
- {"__label__", LABEL, NORID},
- {"default", DEFAULT, NORID,},
+ {"void", TYPESPEC, RID_VOID,},
+ {"asm", ASM_KEYWORD, NORID,},
+ {"break", BREAK, NORID,},
{"const", TYPE_QUAL, RID_CONST,},
{"static", SCSPEC, RID_STATIC,},
- {"",}, {"",},
- {"__alignof", ALIGNOF, NORID},
+ {"mutable", SCSPEC, RID_MUTABLE,},
+ {"protected", VISSPEC, RID_PROTECTED,},
+ {"",}, {"",}, {"",}, {"",},
+ {"new", NEW, NORID,},
+ {"__signed", TYPESPEC, RID_SIGNED},
{"virtual", SCSPEC, RID_VIRTUAL,},
- {"union", AGGR, RID_UNION,},
+ {"extern", SCSPEC, RID_EXTERN,},
{"",}, {"",}, {"",},
- {"signature", AGGR, RID_SIGNATURE /* Extension */,},
- {"headof", HEADOF, NORID,},
- {"",},
- {"inline", SCSPEC, RID_INLINE,},
- {"overload", OVERLOAD, NORID,},
- {"",},
- {"volatile", TYPE_QUAL, RID_VOLATILE,},
- {"",}, {"",}, {"",}, {"",},
+ {"float", TYPESPEC, RID_FLOAT,},
+ {"",}, {"",},
{"register", SCSPEC, RID_REGISTER,},
- {"",},
- {"public", VISSPEC, RID_PUBLIC,},
+ {"__extension__", EXTENSION, NORID},
{"",}, {"",},
{"__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,},
- {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"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,},
- {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
- {"",}, {"",}, {"",},
- {"dynamic_cast", DYNAMIC_CAST, NORID,},
- {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
- {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
+ {"const_cast", CONST_CAST, NORID,},
+ {"catch", CATCH, 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)
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 8e70143..6ce92a3 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -643,7 +643,7 @@ emit_base_init (t, immediately)
/* member could be, for example, a CONST_DECL for an enumerated
tag; we don't want to try to initialize that, since it already
has a value. */
- if (TREE_CODE (member) != FIELD_DECL)
+ if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member))
continue;
name = DECL_NAME (member);
@@ -2087,8 +2087,7 @@ build_offset_ref (cname, name)
if (t == NULL_TREE)
{
- cp_error ("`%D' is not a member of type `%T'", name,
- IDENTIFIER_TYPE_VALUE (cname));
+ cp_error ("`%D' is not a member of type `%T'", name, type);
return error_mark_node;
}
@@ -2748,7 +2747,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
/* We can call pushdecl here, because the TREE_CHAIN of this
FUNCTION_DECL is not needed for other purposes. */
- decl = pushdecl_top_level (decl);
+ decl = pushdecl (decl);
make_decl_rtl (decl, NULL_PTR, 1);
add_friend (current_class_type, decl);
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 7c88ba5..22cf0a5 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -662,6 +662,9 @@ init_lex ()
ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
SET_IDENTIFIER_AS_LIST (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++. */
ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h
index 5288a02..f9bf3f1 100644
--- a/gcc/cp/lex.h
+++ b/gcc/cp/lex.h
@@ -65,6 +65,7 @@ enum rid
RID_RAISES,
RID_AUTO,
RID_MUTABLE,
+ RID_TEMPLATE,
RID_SIGNATURE,
/* Before adding enough to get up to 64, the RIDBIT_* macros
will have to be changed a little. */
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index f46f70a..dd8a96a 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -80,8 +80,6 @@ void yyerror ();
error message if the user supplies an empty conditional expression. */
static char *cond_stmt_keyword;
-static int doing_explicit;
-
/* Nonzero if we have an `extern "C"' acting as an extern specifier. */
int have_extern_spec;
int used_extern_spec;
@@ -153,7 +151,7 @@ empty_parms ()
%token <itype> VISSPEC
%token DELETE NEW OVERLOAD THIS OPERATOR
%token LEFT_RIGHT TEMPLATE
-%token TYPEID DYNAMIC_CAST
+%token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST
%token <itype> SCOPE
/* Define the operator tokens and their precedences.
@@ -197,7 +195,7 @@ empty_parms ()
%type <code> unop
%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> typed_declspecs reserved_declspecs
%type <ttype> typed_typespecs reserved_typespecquals
@@ -242,7 +240,7 @@ empty_parms ()
%type <ttype> class_head base_class_list
%type <itype> base_class_access_list
%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> forhead.1 operator_name
%type <ttype> object aggr
@@ -261,7 +259,7 @@ empty_parms ()
%type <ttype> qualified_type_name complete_type_name notype_identifier
%type <ttype> complex_type_name nested_name_specifier_1
%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. */
%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
@@ -538,7 +536,6 @@ datadef:
| declmods ';'
{ pedwarn ("empty declaration"); }
| explicit_instantiation ';'
- { doing_explicit = 0; }
| typed_declspecs ';'
{
tree t = $<ttype>$;
@@ -775,16 +772,11 @@ identifier_defn:
| PTYPENAME_DEFN
;
-do_explicit: TEMPLATE %prec EMPTY
- { doing_explicit = 1; }
- ;
-
explicit_instantiation:
- do_explicit specialization template_instantiation
+ TEMPLATE specialization template_instantiation
{ do_type_instantiation ($3 ? $3 : $2); }
- | do_explicit typed_declspecs declarator
+ | TEMPLATE typed_declspecs declarator
{ do_function_instantiation ($2, $3); }
- | do_explicit error
;
template_type:
@@ -925,7 +917,7 @@ xcond:
;
condition:
- typed_typespecs declarator maybe_raises maybeasm maybe_attribute '='
+ type_specifier_seq declarator maybe_raises maybeasm maybe_attribute '='
{ {
tree d;
for (d = getdecls (); d; d = TREE_CHAIN (d))
@@ -953,6 +945,17 @@ condition:
| expr
;
+already_scoped_stmt:
+ '{' '}'
+ { finish_stmt (); }
+ | '{' maybe_label_decls stmts '}'
+ { finish_stmt (); }
+ | '{' maybe_label_decls error '}'
+ { finish_stmt (); }
+ | simple_stmt
+ ;
+
+
nontrivial_exprlist:
expr_no_commas ',' expr_no_commas
{ $$ = tree_cons (NULL_TREE, $$,
@@ -1414,10 +1417,18 @@ primary:
}
}
| functional_cast
- /* Stroustrup RTTI */
| DYNAMIC_CAST '<' type_id '>' '(' expr ')'
{ tree type = groktypename ($3);
$$ = 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 ')'
{ $$ = build_typeid ($3); }
| TYPEID '(' type_id ')'
@@ -2168,8 +2179,8 @@ specialization:
aggr template_type_name ';'
{
yyungetc (';', 1); current_aggr = $$; $$ = $2;
- if (doing_explicit)
- instantiate_class_template ($$, 1);
+ if ($<ttype>0 == ridpointers[(int) RID_TEMPLATE])
+ instantiate_class_template ($$, 2);
}
;
@@ -2644,13 +2655,9 @@ enumerator:
/* ANSI new-type-id (5.3.4) */
new_type_id:
- typed_typespecs new_declarator
- { $$ = build_decl_list ($$, $2); }
- | nonempty_type_quals new_declarator
+ type_specifier_seq new_declarator
{ $$ = build_decl_list ($$, $2); }
- | typed_typespecs %prec EMPTY
- { $$ = build_decl_list ($$, NULL_TREE); }
- | nonempty_type_quals %prec EMPTY
+ | type_specifier_seq %prec EMPTY
{ $$ = build_decl_list ($$, NULL_TREE); }
/* GNU extension to allow arrays of arbitrary types with
non-constant dimension. */
@@ -3100,7 +3107,7 @@ simple_stmt:
cond_stmt_keyword = "while"; }
.pushlevel paren_cond_or_null
{ expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
- implicitly_scoped_stmt
+ already_scoped_stmt
{ expand_end_bindings (getdecls (), kept_level_p (), 1);
poplevel (kept_level_p (), 1, 0);
pop_momentary ();
@@ -3131,14 +3138,14 @@ simple_stmt:
/* Don't let the tree nodes for $7 be discarded
by clear_momentary during the parsing of the next stmt. */
{ push_momentary (); }
- implicitly_scoped_stmt
+ already_scoped_stmt
{ 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);
poplevel (kept_level_p (), 1, 0);
pop_momentary ();
+ expand_loop_continue_here ();
+ if ($7) cplus_expand_expr_stmt ($7);
+ pop_momentary ();
expand_end_loop ();
finish_stmt (); }
| forhead.2
@@ -3153,14 +3160,14 @@ simple_stmt:
by clear_momentary during the parsing of the next stmt. */
{ push_momentary ();
$<itype>8 = lineno; }
- implicitly_scoped_stmt
+ already_scoped_stmt
{ 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);
poplevel (kept_level_p (), 1, 0);
pop_momentary ();
+ expand_loop_continue_here ();
+ if ($7) cplus_expand_expr_stmt ($7);
+ pop_momentary ();
expand_end_loop ();
finish_stmt ();
}
@@ -3422,11 +3429,6 @@ ansi_try_stmts:
}
;
-optional_identifier:
- /* empty */
- { $$ = NULL_TREE; }
- | identifier ;
-
handler_seq:
/* empty */
| handler_seq CATCH
@@ -3435,10 +3437,21 @@ handler_seq:
{ expand_end_catch_block (); }
;
+type_specifier_seq:
+ typed_typespecs %prec EMPTY
+ | nonempty_type_quals %prec EMPTY
+ ;
+
handler_args:
'(' ELLIPSIS ')'
{ 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); }
;
@@ -3704,33 +3717,11 @@ maybe_raises:
{ $$ = $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:
type_id
{ $$ = build_decl_list (NULL_TREE, $$); }
;
-raise_identifiers:
- raise_identifier
- | raise_identifiers ',' raise_identifier
- {
- TREE_CHAIN ($3) = $$;
- $$ = $3;
- }
- ;
-
ansi_raise_identifiers:
ansi_raise_identifier
| ansi_raise_identifiers ',' ansi_raise_identifier
@@ -3825,7 +3816,7 @@ operator_name:
| operator DELETE '[' ']'
{ $$ = ansi_opname[VEC_DELETE_EXPR]; }
/* Names here should be looked up in class scope ALSO. */
- | operator typed_typespecs conversion_declarator
+ | operator type_specifier_seq conversion_declarator
{ $$ = grokoptypename ($2, $3); }
| operator error
{ $$ = ansi_opname[ERROR_MARK]; }
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 377d4a7..528bbdd 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -265,12 +265,16 @@ end_template_decl (d1, d2, is_class, defn)
&& DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE)
{
tree ctx = DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl));
- tree tmpl;
+ tree tmpl, t;
my_friendly_assert (TREE_CODE (ctx) == UNINSTANTIATED_P_TYPE, 266);
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) =
- perm_tree_cons (DECL_NAME (decl), decl,
- DECL_TEMPLATE_MEMBERS (tmpl));
+ perm_tree_cons (DECL_NAME (decl), decl, DECL_TEMPLATE_MEMBERS (tmpl));
+ already_there:
poplevel (0, 0, 0);
poplevel (0, 0, 0);
}
@@ -1459,6 +1463,9 @@ tsubst (t, args, nargs, in_decl)
layout_type (r);
return r;
}
+ case OFFSET_TYPE:
+ return build_offset_type
+ (tsubst (TYPE_OFFSET_BASETYPE (t), args, nargs, in_decl), type);
case FUNCTION_TYPE:
case METHOD_TYPE:
{
@@ -2008,10 +2015,19 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
if (targs[idx] == arg)
return 0;
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. */
if (TREE_CODE (TREE_VEC_ELT (tparms, idx)) != IDENTIFIER_NODE)
return 1;
+ /* Allow trivial conversions. */
+ if (TYPE_READONLY (parm) < TYPE_READONLY (arg)
+ || TYPE_VOLATILE (parm) < TYPE_VOLATILE (arg))
+ return 1;
targs[idx] = arg;
return 0;
case TEMPLATE_CONST_PARM:
@@ -2136,8 +2152,12 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
return unify (tparms, targs, ntparms, TYPE_PTRMEMFUNC_FN_TYPE (parm),
arg, nsubsts);
- /* Unification of something that is not a template fails. (mrs) */
- return 1;
+ /* Allow trivial conversions. */
+ 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:
if (TREE_CODE (arg) != METHOD_TYPE)
@@ -2150,7 +2170,16 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
check_args:
return type_unification (tparms, targs, TYPE_ARG_TYPES (parm),
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:
sorry ("use of `%s' in template type unification",
tree_code_name [(int) TREE_CODE (parm)]);
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 946763c..c81f1e1 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1134,7 +1134,7 @@ lookup_field (xbasetype, name, protect, want_type)
if (errstr && protect)
{
- error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
+ cp_error (errstr, name, type);
return error_mark_node;
}
return rval;
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index edb0b78a..d8df8e4 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -94,9 +94,6 @@ lvalue_p (ref)
return (lvalue_p (TREE_OPERAND (ref, 1))
&& lvalue_p (TREE_OPERAND (ref, 2)));
- case MODIFY_EXPR:
- return 1;
-
case COMPOUND_EXPR:
return lvalue_p (TREE_OPERAND (ref, 1));
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 03ca722..490d998 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -47,7 +47,6 @@ static tree pointer_int_sum ();
static tree pointer_diff ();
static tree convert_sequence ();
/* static */ tree unary_complex_lvalue ();
-static void pedantic_lvalue_warning ();
tree truthvalue_conversion ();
extern rtx original_result_rtx;
@@ -223,10 +222,7 @@ commonparms (p1, p2)
if (cmp < 0)
my_friendly_abort (111);
if (cmp == 0)
- {
- error ("redeclaration of default argument %d", i+1);
- any_change = 1;
- }
+ any_change = 1;
TREE_PURPOSE (n) = TREE_PURPOSE (p2);
}
if (TREE_VALUE (p1) != TREE_VALUE (p2))
@@ -411,7 +407,7 @@ common_type (t1, t2)
return t1;
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)))
{
/* Get this value the long way, since TYPE_METHOD_BASETYPE
@@ -642,6 +638,9 @@ comptypes (type1, type2, strict)
case TEMPLATE_TYPE_PARM:
return 1;
+
+ case UNINSTANTIATED_P_TYPE:
+ return UPT_TEMPLATE (t1) == UPT_TEMPLATE (t2);
}
return 0;
}
@@ -1340,9 +1339,10 @@ build_object_ref (datum, basetype, field)
else if (is_aggr_typedef (basetype, 1))
{
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),
- field, NULL_TREE, 1);
+ field, binfo, 1);
}
return error_mark_node;
}
@@ -3006,12 +3006,14 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
;
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");
}
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");
}
else if ((TYPE_SIZE (tt0) != 0) != (TYPE_SIZE (tt1) != 0))
@@ -3457,13 +3459,6 @@ pointer_int_sum (resultcode, ptrop, intop)
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 (pedantic || warn_pointer_arith)
@@ -3491,6 +3486,13 @@ pointer_int_sum (resultcode, ptrop, intop)
else
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
contains a constant term, apply distributive law
and multiply that constant term separately.
@@ -3882,7 +3884,6 @@ build_unary_op (code, xarg, noconvert)
case FIX_CEIL_EXPR:
{
tree incremented, modify, value;
- pedantic_lvalue_warning (CONVERT_EXPR);
arg = stabilize_reference (arg);
if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
value = arg;
@@ -4158,17 +4159,18 @@ unary_complex_lvalue (code, arg)
if (TREE_CODE (arg) == COMPOUND_EXPR)
{
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),
TREE_OPERAND (arg, 0), real_result);
}
/* Handle (a ? b : c) used as an "lvalue". */
if (TREE_CODE (arg) == COND_EXPR)
- {
- pedantic_lvalue_warning (COND_EXPR);
- return rationalize_conditional_expr (code, arg);
- }
+ 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)
return 0;
@@ -4295,19 +4297,6 @@ unary_complex_lvalue (code, arg)
/* Don't let anything else be handled specially. */
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
address of it; it should not be allocated in a register.
@@ -4785,6 +4774,24 @@ build_compound_expr (list)
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. */
tree
@@ -5294,7 +5301,6 @@ build_modify_expr (lhs, modifycode, rhs)
/* Handle (a, b) used as an "lvalue". */
case COMPOUND_EXPR:
- pedantic_lvalue_warning (COMPOUND_EXPR);
newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
modifycode, rhs);
if (TREE_CODE (newrhs) == ERROR_MARK)
@@ -5302,9 +5308,14 @@ build_modify_expr (lhs, modifycode, rhs)
return build (COMPOUND_EXPR, lhstype,
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". */
case COND_EXPR:
- pedantic_lvalue_warning (COND_EXPR);
rhs = save_expr (rhs);
{
/* Produce (a ? (b = rhs) : (c = rhs))
@@ -5450,7 +5461,7 @@ build_modify_expr (lhs, modifycode, rhs)
convert (lhstype, newrhs)));
if (TREE_CODE (result) == ERROR_MARK)
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)
return here before checking if RHS is of complete type. */
if (codel == REFERENCE_TYPE)
- return convert_to_reference ((exp ? exp : error_mark_node),
- type, rhs, fndecl, parmnum, errtype,
- 0, flags);
+ return convert_to_reference (type, rhs, CONV_IMPLICIT, flags,
+ exp ? exp : error_mark_node);
rhs = require_complete_type (rhs);
if (rhs == error_mark_node)
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 53106b2..858896a 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -59,7 +59,7 @@ binfo_or_else (parent_or_type, type)
{
tree binfo;
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 == error_mark_node)
@@ -738,7 +738,10 @@ digest_init (type, init, tail)
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");
TREE_TYPE (string) = type;
if (TYPE_DOMAIN (type) != 0
@@ -752,7 +755,7 @@ digest_init (type, init, tail)
counted in the length of the constant, but in C++ this would
be invalid. */
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;
}