summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1996-02-20 20:35:10 +0000
committerMike Stump <mrs@gcc.gnu.org>1996-02-20 20:35:10 +0000
commitcffa87298012df49b1a3bafa4d9d7a66c155378d (patch)
tree6ee9a4da1768cb23abf74781faddd9d48d5f4b37 /gcc/cp
parent1144563fbc40c80298e1477c67c0614d1e9a917e (diff)
downloadgcc-cffa87298012df49b1a3bafa4d9d7a66c155378d.tar.gz
82nd Cygnus<->FSF merge
From-SVN: r11328
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog101
-rw-r--r--gcc/cp/class.c35
-rw-r--r--gcc/cp/cp-tree.def4
-rw-r--r--gcc/cp/cp-tree.h15
-rw-r--r--gcc/cp/decl.c172
-rw-r--r--gcc/cp/decl2.c34
-rw-r--r--gcc/cp/error.c7
-rw-r--r--gcc/cp/expr.c13
-rw-r--r--gcc/cp/gxxint.texi18
-rw-r--r--gcc/cp/init.c82
-rw-r--r--gcc/cp/parse.y76
-rw-r--r--gcc/cp/search.c8
-rw-r--r--gcc/cp/typeck.c41
13 files changed, 374 insertions, 232 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 72617e03ce6..217146b76c9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,8 +1,107 @@
+Thu Feb 15 18:44:42 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (cp_finish_decl): Delay emitting the debug information for
+ a typedef that has been installed as the canonical typedef, if the
+ type has not yet been defined.
+
+Thu Feb 15 09:39:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (grokfield): Still call pop_nested_class for access decls.
+
+Wed Feb 14 17:30:04 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (lookup_label): Call label_rtx.
+
+ * decl.c (make_binding_level): New function.
+ (pushlevel, pushlevel_class): Call it instead of explicit
+ duplicate calls to xmalloc.
+
+ * decl.c (init_decl_processing): Delete useless build_pointer_type
+ call.
+
+ * decl.c (float_ftype_float, ldouble_ftype_ldouble): Add definitions.
+ (sizet_ftype_string): Delete variable.
+ (init_decl_processing): Add built-in functions fabsf, fabsl,
+ sqrtf, sqrtl, sinf, sin, sinl, cosf, cos, cosl. New local
+ variable strlen_ftype, used for strlen.
+
+Wed Feb 14 16:21:25 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (push_to_top_level): Start from current_binding_level
+ again for now; the stl hacks depend on g++ being broken in this
+ way, and it'll be fixed in the template rewrite.
+
+ * tree.def: Add USING_DECL.
+ * decl2.c (do_class_using_decl): Implement.
+ (grokfield): Pass access decls off to do_class_using_decl instead of
+ grokdeclarator.
+ * error.c (dump_decl): Handle USING_DECLs.
+ * decl.c (grokdeclarator): Remove code for handling access decls.
+ * class.c (finish_struct_1): Adjust accordingly, treat using-decls
+ as access decls for now.
+ (finish_struct): Don't check USING_DECLs for other uses of the name.
+
+ * search.c (get_matching_virtual): Use cp_error_at.
+
+Wed Feb 14 10:36:58 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * typeck.c (comptypes): Default COMP_TYPE_ATTRIBUTES to 1, to
+ match c-typeck.c.
+ (self_promoting_args_p): Move the check that TYPE is non-nil
+ before trying to look at its main variant.
+ (unsigned_type, signed_type): Add checking of DI/SI/HI/QI nodes.
+
+ * cp-tree.h (DECL_WAITING_FRIENDS, SET_DECL_WAITING_FRIENDS):
+ Delete macros.
+ * init.c (xref_friend, embrace_waiting_friends): Delete functions.
+ (do_friend): Delete call to xref_friend.
+ * class.c (finish_struct_1): Delete call to embrace_waiting_friends.
+
+ * typeck.c (convert_sequence): #if 0 unused function.
+
+ * cp-tree.h (DECL_IN_MEMORY_P): New macro w/ the check that used to
+ be in decl_in_memory_p.
+ (decl_in_memory_p): Delete decl.
+ * expr.c (decl_in_memory_p): Delete fn.
+ * typeck.c (mark_addressable): Use DECL_IN_MEMORY_P.
+
+ * decl.c (cp_finish_decl): Use DECL_IN_MEMORY_P.
+
+Tue Feb 13 12:51:21 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): Check for a pure-specifier on a
+ non-virtual function here.
+
+ * decl2.c (grok_function_init): Don't check whether the function
+ is virtual here.
+ (grokfield): Don't call check_for_override here.
+
+ * decl.c (push_to_top_level): Start from inner_binding_level,
+ check class_shadowed in class levels.
+
+Mon Feb 12 17:46:59 1996 Mike Stump <mrs@cygnus.com>
+
+ * decl.c (resume_level): Ignore things that don't have names, instead
+ of core dumping.
+
+Mon Feb 12 15:47:44 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl2.c (grokfield): Set DECL_VINDEX properly for FUNCTION_DECLs.
+
+Sat Feb 10 17:59:45 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (finish_struct_1): Set DECL_VINDEX properly on a
+ synthesized dtor.
+
+ * parse.y (complete_type_name): Bind global_scope earlier.
+ (complex_type_name): Ditto.
+ (qualified_type_name): Remove.
+
Thu Feb 8 15:15:14 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grokfndecl): Move code that looks for virtuals in base
classes...
- * class.c (fixup_virtual): ... to a new function.
+ * class.c (check_for_override): ... to a new function.
(finish_struct_1): Call it.
* cp-tree.h: Declare warn_sign_compare.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index a5c8f386650..6b8f8809855 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2758,7 +2758,7 @@ mark_overriders (fndecl, base_fndecls)
mark this field as being virtual as well. */
void
-fixup_virtual (decl, ctype)
+check_for_override (decl, ctype)
tree decl, ctype;
{
tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
@@ -3177,7 +3177,9 @@ finish_struct_1 (t, attributes, warn_anon)
DECL_SAVED_INSNS (x) = NULL_RTX;
DECL_FIELD_SIZE (x) = 0;
- fixup_virtual (x, t);
+ check_for_override (x, t);
+ if (DECL_ABSTRACT_VIRTUAL_P (x) && ! DECL_VINDEX (x))
+ cp_error_at ("initializer specified for non-virtual method `%D'", x);
/* The name of the field is the original field name
Save this in auxiliary field for later overloading. */
@@ -3198,19 +3200,36 @@ finish_struct_1 (t, attributes, warn_anon)
GNU_xref_member (current_class_name, x);
/* Handle access declarations. */
- if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF)
+ if (TREE_CODE (x) == USING_DECL)
{
- tree fdecl = TREE_OPERAND (DECL_NAME (x), 1);
+ tree ctype = DECL_INITIAL (x);
+ tree sname = DECL_NAME (x);
tree access
= TREE_PRIVATE (x) ? access_private_node :
TREE_PROTECTED (x) ? access_protected_node : access_public_node;
+ tree fdecl, binfo;
if (last_x)
TREE_CHAIN (last_x) = TREE_CHAIN (x);
else
fields = TREE_CHAIN (x);
- access_decls = tree_cons (access, fdecl, access_decls);
+ binfo = binfo_or_else (ctype, t);
+ if (! binfo)
+ continue;
+
+ if (sname == constructor_name (ctype)
+ || sname == constructor_name_full (ctype))
+ cp_error_at ("using-declaration for constructor", x);
+
+ fdecl = lookup_field (binfo, sname, 0, 0);
+ if (! fdecl)
+ fdecl = lookup_fnfields (binfo, sname, 0);
+
+ if (fdecl)
+ access_decls = tree_cons (access, fdecl, access_decls);
+ else
+ cp_error_at ("no members matching `%D' in `%#T'", x, ctype);
continue;
}
@@ -3529,6 +3548,7 @@ finish_struct_1 (t, attributes, warn_anon)
{
/* Here we must cons up a destructor on the fly. */
tree dtor = cons_up_default_function (t, name, needs_virtual_dtor != 0);
+ check_for_override (dtor, t);
/* If we couldn't make it work, then pretend we didn't need it. */
if (dtor == void_type_node)
@@ -4125,9 +4145,6 @@ finish_struct_1 (t, attributes, warn_anon)
else if (TYPE_NEEDS_CONSTRUCTING (t))
build_class_init_list (t);
- if (! IS_SIGNATURE (t))
- embrace_waiting_friends (t);
-
/* Write out inline function definitions. */
do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t));
CLASSTYPE_INLINE_FRIENDS (t) = 0;
@@ -4289,7 +4306,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
/* Check for inconsistent use of this name in the class body.
Enums, types and static vars have already been checked. */
- if (TREE_CODE (x) != TYPE_DECL
+ if (TREE_CODE (x) != TYPE_DECL && TREE_CODE (x) != USING_DECL
&& TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL)
{
tree name = DECL_NAME (x);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index fabc3e115b8..197e9c90e0f 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -114,3 +114,7 @@ DEFTREECODE (THUNK_DECL, "thunk_decl", "d", 0)
/* A namespace declaration. */
DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0)
+
+/* A using declaration. DECL_INITIAL contains the specified scope.
+ This is not an alias, but is later expanded into multiple aliases. */
+DEFTREECODE (USING_DECL, "using_decl", "d", 0)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 05f12b99ce6..67e0de3a82a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -973,6 +973,14 @@ struct lang_decl
#define TREE_READONLY_DECL_P(NODE) \
(TREE_READONLY (NODE) && TREE_CODE_CLASS (TREE_CODE (NODE)) == 'd')
+/* Non-zero iff DECL is memory-based. The DECL_RTL of
+ certain const variables might be a CONST_INT, or a REG
+ in some cases. We cannot use `memory_operand' as a test
+ here because on most RISC machines, a variable's address
+ is not, by itself, a legitimate address. */
+#define DECL_IN_MEMORY_P(NODE) \
+ (DECL_RTL (NODE) != NULL_RTX && GET_CODE (DECL_RTL (NODE)) == MEM)
+
/* For FUNCTION_DECLs: return the language in which this decl
was declared. */
#define DECL_LANGUAGE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.language)
@@ -1302,12 +1310,6 @@ extern int flag_new_for_scope;
/* C++: all of these are overloaded! These apply only to TYPE_DECLs. */
#define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE))
-#if 0
-#define DECL_UNDEFINED_FRIENDS(NODE) ((NODE)->decl.result)
-#endif
-#define DECL_WAITING_FRIENDS(NODE) ((tree)(NODE)->decl.rtl)
-#define SET_DECL_WAITING_FRIENDS(NODE,VALUE) \
- ((NODE)->decl.rtl=(struct rtx_def*)VALUE)
/* The DECL_ACCESS is used to record under which context
special access rules apply. */
@@ -2124,7 +2126,6 @@ extern tree start_anon_func PROTO((void));
/* skip cplus_expand_expr */
extern void init_cplus_expand PROTO((void));
extern void fixup_result_decl PROTO((tree, struct rtx_def *));
-extern int decl_in_memory_p PROTO((tree));
extern tree unsave_expr_now PROTO((tree));
/* in rtti.c */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index f3f16f85dee..ee66250cdb2 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -220,6 +220,8 @@ tree default_function_type;
tree double_ftype_double, double_ftype_double_double;
tree int_ftype_int, long_ftype_long;
+tree float_ftype_float;
+tree ldouble_ftype_ldouble;
/* Function type `void (void *, void *, int)' and similar ones. */
@@ -228,9 +230,6 @@ tree void_ftype_ptr_ptr_int, int_ftype_ptr_ptr_int, void_ftype_ptr_int_int;
/* Function type `char *(char *, char *)' and similar ones */
tree string_ftype_ptr_ptr, int_ftype_string_string;
-/* Function type `size_t (const char *)' */
-tree sizet_ftype_string;
-
/* Function type `int (const void *, const void *, size_t)' */
tree int_ftype_cptr_cptr_sizet;
@@ -796,6 +795,16 @@ resume_binding_level (b)
#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
}
+/* Create a new `struct binding_level'. */
+
+static
+struct binding_level *
+make_binding_level ()
+{
+ /* NOSTRICT */
+ return (struct binding_level *) xmalloc (sizeof (struct binding_level));
+}
+
/* Nonzero if we are currently in the global binding level. */
int
@@ -924,9 +933,9 @@ pushlevel (tag_transparent)
}
else
{
- /* Create a new `struct binding_level'. */
- newlevel = (struct binding_level *) xmalloc (sizeof (struct binding_level));
+ newlevel = make_binding_level ();
}
+
push_binding_level (newlevel, tag_transparent, keep_next_level_flag);
GNU_xref_start_scope ((HOST_WIDE_INT) newlevel);
keep_next_level_flag = 0;
@@ -1283,8 +1292,11 @@ resume_level (b)
for (link = decls; link; link = TREE_CHAIN (link))
{
- if (DECL_NAME (link) != NULL_TREE)
- IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = link;
+ /* If it doesn't have a name, there is nothing left to do with it. */
+ if (DECL_NAME (link) == NULL_TREE)
+ continue;
+
+ IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = link;
/* If this is a TYPE_DECL, push it into the type value slot. */
if (TREE_CODE (link) == TYPE_DECL)
@@ -1366,8 +1378,7 @@ pushlevel_class ()
}
else
{
- /* Create a new `struct binding_level'. */
- newlevel = (struct binding_level *) xmalloc (sizeof (struct binding_level));
+ newlevel = make_binding_level ();
}
#if defined(DEBUG_CP_BINDING_LEVELS)
@@ -1818,10 +1829,10 @@ push_to_top_level ()
continue;
old_bindings = store_bindings (b->names, old_bindings);
- /* We also need to check type_shadowed to save class-level type
+ /* We also need to check class_shadowed to save class-level type
bindings, since pushclass doesn't fill in b->names. */
if (b->parm_flag == 2)
- old_bindings = store_bindings (b->type_shadowed, old_bindings);
+ old_bindings = store_bindings (b->class_shadowed, old_bindings);
/* Unwind type-value slots back to top level. */
for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
@@ -3754,6 +3765,9 @@ lookup_label (id)
decl = build_decl (LABEL_DECL, id, void_type_node);
+ /* Make sure every label has an rtx. */
+ label_rtx (decl);
+
/* A label not explicitly declared must be local to where it's ref'd. */
DECL_CONTEXT (decl) = current_function_decl;
@@ -4016,8 +4030,8 @@ storetags (tags)
static tree
lookup_tag (form, name, binding_level, thislevel_only)
enum tree_code form;
- struct binding_level *binding_level;
tree name;
+ struct binding_level *binding_level;
int thislevel_only;
{
register struct binding_level *level;
@@ -4561,12 +4575,12 @@ void
init_decl_processing ()
{
tree decl;
- register tree endlink, int_endlink, double_endlink, ptr_endlink;
+ register tree endlink, int_endlink, double_endlink, ptr_endlink, float_endlink;
tree fields[20];
/* Either char* or void*. */
tree traditional_ptr_type_node;
/* Data type of memcpy. */
- tree memcpy_ftype;
+ tree memcpy_ftype, strlen_ftype;
int wchar_type_size;
tree temp;
tree array_domain_type;
@@ -4810,7 +4824,6 @@ init_decl_processing ()
default_function_type
= build_function_type (integer_type_node, NULL_TREE);
- build_pointer_type (default_function_type);
ptr_type_node = build_pointer_type (void_type_node);
const_ptr_type_node =
@@ -4819,11 +4832,21 @@ init_decl_processing ()
endlink = void_list_node;
int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
double_endlink = tree_cons (NULL_TREE, double_type_node, endlink);
+ float_endlink = tree_cons (NULL_TREE, float_type_node, endlink);
ptr_endlink = tree_cons (NULL_TREE, ptr_type_node, endlink);
+ float_ftype_float
+ = build_function_type (float_type_node,
+ tree_cons (NULL_TREE, float_type_node, endlink));
+
double_ftype_double
= build_function_type (double_type_node, double_endlink);
+ ldouble_ftype_ldouble
+ = build_function_type (long_double_type_node,
+ tree_cons (NULL_TREE, long_double_type_node,
+ endlink));
+
double_ftype_double_double
= build_function_type (double_type_node,
tree_cons (NULL_TREE, double_type_node,
@@ -4871,7 +4894,7 @@ init_decl_processing ()
const_string_type_node,
endlink)));
- sizet_ftype_string /* strlen prototype */
+ strlen_ftype /* strlen prototype */
= build_function_type (sizetype,
tree_cons (NULL_TREE, const_string_type_node,
endlink));
@@ -4910,13 +4933,13 @@ init_decl_processing ()
endlink)),
BUILT_IN_FRAME_ADDRESS, NULL_PTR);
-
builtin_function ("__builtin_alloca",
build_function_type (ptr_type_node,
tree_cons (NULL_TREE,
sizetype,
endlink)),
BUILT_IN_ALLOCA, "alloca");
+ builtin_function ("__builtin_ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR);
/* Define alloca, ffs as builtins.
Declare _exit just to mark it as volatile. */
if (! flag_no_builtin && !flag_no_nonansi_builtin)
@@ -4941,20 +4964,15 @@ init_decl_processing ()
DECL_BUILT_IN_NONANSI (temp) = 1;
}
- builtin_function ("__builtin_abs", int_ftype_int,
- BUILT_IN_ABS, NULL_PTR);
- builtin_function ("__builtin_fabs", double_ftype_double,
- BUILT_IN_FABS, NULL_PTR);
+ builtin_function ("__builtin_abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR);
+ builtin_function ("__builtin_fabsf", float_ftype_float, BUILT_IN_FABS,
+ NULL_PTR);
+ builtin_function ("__builtin_fabs", double_ftype_double, BUILT_IN_FABS,
+ NULL_PTR);
+ builtin_function ("__builtin_fabsl", ldouble_ftype_ldouble, BUILT_IN_FABS,
+ NULL_PTR);
builtin_function ("__builtin_labs", long_ftype_long,
BUILT_IN_LABS, NULL_PTR);
- builtin_function ("__builtin_ffs", int_ftype_int,
- BUILT_IN_FFS, NULL_PTR);
- builtin_function ("__builtin_fsqrt", double_ftype_double,
- BUILT_IN_FSQRT, NULL_PTR);
- builtin_function ("__builtin_sin", double_ftype_double,
- BUILT_IN_SIN, "sin");
- builtin_function ("__builtin_cos", double_ftype_double,
- BUILT_IN_COS, "cos");
builtin_function ("__builtin_saveregs",
build_function_type (ptr_type_node, NULL_TREE),
BUILT_IN_SAVEREGS, NULL_PTR);
@@ -5002,8 +5020,26 @@ init_decl_processing ()
BUILT_IN_STRCMP, "strcmp");
builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr,
BUILT_IN_STRCPY, "strcpy");
- builtin_function ("__builtin_strlen", sizet_ftype_string,
+ builtin_function ("__builtin_strlen", strlen_ftype,
BUILT_IN_STRLEN, "strlen");
+ builtin_function ("__builtin_sqrtf", float_ftype_float,
+ BUILT_IN_FSQRT, "sqrtf");
+ builtin_function ("__builtin_fsqrt", double_ftype_double,
+ BUILT_IN_FSQRT, NULL_PTR);
+ builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
+ BUILT_IN_FSQRT, "sqrtl");
+ builtin_function ("__builtin_sinf", float_ftype_float,
+ BUILT_IN_SIN, "sinf");
+ builtin_function ("__builtin_sin", double_ftype_double,
+ BUILT_IN_SIN, "sin");
+ builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
+ BUILT_IN_SIN, "sinl");
+ builtin_function ("__builtin_cosf", float_ftype_float,
+ BUILT_IN_COS, "cosf");
+ builtin_function ("__builtin_cos", double_ftype_double,
+ BUILT_IN_COS, "cos");
+ builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
+ BUILT_IN_COS, "cosl");
if (!flag_no_builtin)
{
@@ -5012,15 +5048,27 @@ init_decl_processing ()
builtin_function ("fabs", double_ftype_double, BUILT_IN_FABS, NULL_PTR);
builtin_function ("labs", long_ftype_long, BUILT_IN_LABS, NULL_PTR);
#endif
+ builtin_function ("fabsf", float_ftype_float, BUILT_IN_FABS, NULL_PTR);
+ builtin_function ("fabsl", ldouble_ftype_ldouble, BUILT_IN_FABS,
+ NULL_PTR);
builtin_function ("memcpy", memcpy_ftype, BUILT_IN_MEMCPY, NULL_PTR);
builtin_function ("memcmp", int_ftype_cptr_cptr_sizet, BUILT_IN_MEMCMP,
NULL_PTR);
- builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP, NULL_PTR);
+ builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP,
+ NULL_PTR);
builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY,
NULL_PTR);
- builtin_function ("strlen", sizet_ftype_string, BUILT_IN_STRLEN, NULL_PTR);
+ builtin_function ("strlen", strlen_ftype, BUILT_IN_STRLEN, NULL_PTR);
+ builtin_function ("sqrtf", float_ftype_float, BUILT_IN_FSQRT, NULL_PTR);
+ builtin_function ("sqrt", double_ftype_double, BUILT_IN_FSQRT, NULL_PTR);
+ builtin_function ("sqrtl", ldouble_ftype_ldouble, BUILT_IN_FSQRT,
+ NULL_PTR);
+ builtin_function ("sinf", float_ftype_float, BUILT_IN_SIN, NULL_PTR);
builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR);
+ builtin_function ("sinl", ldouble_ftype_ldouble, BUILT_IN_SIN, NULL_PTR);
+ builtin_function ("cosf", float_ftype_float, BUILT_IN_COS, NULL_PTR);
builtin_function ("cos", double_ftype_double, BUILT_IN_COS, NULL_PTR);
+ builtin_function ("cosl", ldouble_ftype_ldouble, BUILT_IN_COS, NULL_PTR);
/* Declare these functions volatile
to avoid spurious "control drops through" warnings. */
@@ -5047,13 +5095,14 @@ init_decl_processing ()
builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, NULL_PTR);
builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR,
NULL_PTR);
- builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, NULL_PTR);
+ builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL,
+ NULL_PTR);
builtin_function ("__builtin_fmod", double_ftype_double_double,
BUILT_IN_FMOD, NULL_PTR);
builtin_function ("__builtin_frem", double_ftype_double_double,
BUILT_IN_FREM, NULL_PTR);
- builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, BUILT_IN_MEMSET,
- NULL_PTR);
+ builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int,
+ BUILT_IN_MEMSET, NULL_PTR);
builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP,
NULL_PTR);
builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN,
@@ -6109,6 +6158,14 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
CLASSTYPE_GOT_SEMICOLON (type) = 1;
}
GNU_xref_decl (current_function_decl, decl);
+
+ /* If we have installed this as the canonical typedef for this
+ type, and that type has not been defined yet, delay emitting
+ the debug informaion for it, as we will emit it later. */
+ if (TYPE_NAME (TREE_TYPE (decl)) == decl
+ && TYPE_SIZE (TREE_TYPE (decl)) == NULL_TREE)
+ TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
+
rest_of_decl_compilation (decl, NULL_PTR,
DECL_CONTEXT (decl) == NULL_TREE, 0);
goto finish_end;
@@ -6538,7 +6595,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
}
if (link == NULL)
{
- if (DECL_RTL (decl) && GET_CODE (DECL_RTL (decl)) == MEM)
+ if (DECL_IN_MEMORY_P (decl))
preserve_temp_slots (DECL_RTL (decl));
break;
}
@@ -7698,10 +7755,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
opaque_typedef = 1;
type = copy_node (opaque_type_node);
}
- /* access declaration */
- else if (decl_context == FIELD && declarator
- && TREE_CODE (declarator) == SCOPE_REF)
- type = void_type_node;
else
{
if (funcdef_flag)
@@ -8719,50 +8772,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
else if (TYPE_SIZE (ctype) != NULL_TREE
|| (RIDBIT_SETP (RID_TYPEDEF, specbits)))
{
- tree t;
/* have to move this code elsewhere in this function.
this code is used for i.e., typedef int A::M; M *pm;
It is? How? jason 10/2/94 */
- if (explicit_int == -1 && decl_context == FIELD
- && funcdef_flag == 0)
- {
- /* The code in here should only be used to build
- stuff that will be grokked as access decls. */
- t = lookup_field (ctype, sname, 0, 0);
- if (t)
- {
- t = build_lang_field_decl (FIELD_DECL, build_nt (SCOPE_REF, ctype, t), type);
- DECL_INITIAL (t) = init;
- return t;
- }
- /* No such field, try member functions. */
- t = lookup_fnfields (TYPE_BINFO (ctype), sname, 0);
- if (t)
- {
- if (flags == DTOR_FLAG)
- t = TREE_VALUE (t);
- else if (CLASSTYPE_METHOD_VEC (ctype)
- && TREE_VALUE (t) == TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), 0))
- {
- /* Don't include destructor with constructors. */
- t = DECL_CHAIN (TREE_VALUE (t));
- if (t == NULL_TREE)
- cp_error ("`%T' does not have any constructors",
- ctype);
- t = build_tree_list (NULL_TREE, t);
- }
- t = build_lang_field_decl (FIELD_DECL, build_nt (SCOPE_REF, ctype, t), type);
- DECL_INITIAL (t) = init;
- return t;
- }
-
- cp_error
- ("field `%D' is not a member of structure `%T'",
- sname, ctype);
- }
-
if (current_class_type)
{
cp_error ("cannot declare member `%T::%s' within `%T'",
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index b7ce4f02700..38af65277f7 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */
extern tree get_file_function_name ();
extern tree cleanups_this_call;
static void grok_function_init ();
+extern int current_class_depth;
/* A list of virtual function tables we must make sure to write out. */
tree pending_vtables;
@@ -1328,11 +1329,20 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
flags = 0;
}
+ if (declspecs == NULL_TREE
+ && TREE_CODE (declarator) == SCOPE_REF)
+ {
+ /* Access declaration */
+ if (TREE_COMPLEXITY (declarator) == current_class_depth)
+ pop_nested_class (1);
+ return do_class_using_decl (declarator);
+ }
+
if (init
&& TREE_CODE (init) == TREE_LIST
&& TREE_VALUE (init) == error_mark_node
&& TREE_CHAIN (init) == NULL_TREE)
- init = NULL_TREE;
+ init = NULL_TREE;
value = grokdeclarator (declarator, declspecs, FIELD, init != 0,
raises, NULL_TREE);
@@ -1867,8 +1877,11 @@ grok_function_init (decl, init)
if (TREE_CODE (type) == FUNCTION_TYPE)
cp_error ("initializer specified for non-member function `%D'", decl);
+#if 0
+ /* We'll check for this in finish_struct_1. */
else if (DECL_VINDEX (decl) == NULL_TREE)
cp_error ("initializer specified for non-virtual method `%D'", decl);
+#endif
else if (integer_zerop (init))
{
#if 0
@@ -3404,10 +3417,23 @@ tree
do_class_using_decl (decl)
tree decl;
{
- tree type;
+ tree name, value;
- /* Ignore for now, unimplemented. */
- return NULL_TREE;
+ if (TREE_CODE (decl) != SCOPE_REF)
+ {
+ cp_error ("using-declaration for non-member at class scope");
+ return NULL_TREE;
+ }
+ name = TREE_OPERAND (decl, 1);
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ {
+ cp_error ("using-declaration for destructor");
+ return NULL_TREE;
+ }
+
+ value = build_lang_field_decl (USING_DECL, name, unknown_type_node);
+ DECL_INITIAL (value) = TREE_OPERAND (decl, 0);
+ return value;
}
void
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index a2d786cc70f..6c7a8382134 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -740,6 +740,13 @@ dump_decl (t, v)
dump_expr (DECL_INITIAL (t), 0);
break;
+ case USING_DECL:
+ OB_PUTS ("using ");
+ dump_type (DECL_INITIAL (t), 0);
+ OB_PUTS ("::");
+ OB_PUTID (DECL_NAME (t));
+ break;
+
default:
sorry ("`%s' not supported by dump_decl",
tree_code_name[(int) TREE_CODE (t)]);
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 814aa3862de..d0d7b494a4c 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -278,19 +278,6 @@ fixup_result_decl (decl, result)
}
}
-/* Return nonzero iff DECL is memory-based. The DECL_RTL of
- certain const variables might be a CONST_INT, or a REG
- in some cases. We cannot use `memory_operand' as a test
- here because on most RISC machines, a variable's address
- is not, by itself, a legitimate address. */
-
-int
-decl_in_memory_p (decl)
- tree decl;
-{
- return DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM;
-}
-
/* Expand this initialization inline and see if it's simple enough that
it can be done at compile-time. */
diff --git a/gcc/cp/gxxint.texi b/gcc/cp/gxxint.texi
index 36c25205669..54581f283ea 100644
--- a/gcc/cp/gxxint.texi
+++ b/gcc/cp/gxxint.texi
@@ -1287,13 +1287,13 @@ Ln: throw value;
copy value onto heap
jump throw (Ln, id, address of copy of value on heap)
- try {
+ try @{
+Lstart: the start of the main EH region
|... ...
+Lend: the end of the main EH region
- } catch (T o) {
+ @} catch (T o) @{
...1
- }
+ @}
Lresume:
nop used to make sure there is something before
the next region ends, if there is one
@@ -1314,7 +1314,7 @@ Lover:
[
[
call throw_type_match
- if (eq) {
+ if (eq) @{
] these lines disappear when there is no catch condition
+Lsregion2:
| ...1
@@ -1322,7 +1322,7 @@ Lover:
|Lhandler: handler for the region Lsregion2-Leregion2
| rethrow (Lresume, same id, same obj);
+Leregion2
- }
+ @}
] there are zero or more of these sections, depending upon how many
catch clauses there are
----------------------------- expand_end_all_catch --------------------------
@@ -1338,7 +1338,7 @@ Ldone:
start_all_catch emits labels: Lresume,
-#end example
+@end example
The __unwind_function takes a pointer to the throw handler, and is
expected to pop the stack frame that was built to call it, as well as
@@ -1348,7 +1348,7 @@ machine state as determined by the context in which we are unwinding
into. The way I normally start is to compile:
void *g;
- foo(void* a) { g = a; }
+ foo(void* a) @{ g = a; @}
with -S, and change the thing that alters the PC (return, or ret
usually) to not alter the PC, making sure to leave all other semantics
@@ -1455,7 +1455,7 @@ descriptor that refers to fully contained code that has been eliminated
should also be removed, although not doing this is harmless in terms of
semantics.
-#end itemize
+@end itemize
The above is not meant to be exhaustive, but does include all things I
have thought of so far. I am sure other limitations exist.
@@ -1517,7 +1517,7 @@ pointer, frame pointer, arg pointer and so on.
The eh archive (~mrs/eh) might be good reading for understanding the Ada
perspective, and some of kenners mindset, and a detailed explanation
-(Message-Id: <9308301130.AA10543@vlsi1.ultra.nyu.edu>) of the concepts
+(Message-Id: <9308301130.AA10543@@vlsi1.ultra.nyu.edu>) of the concepts
involved.
Here is a guide to existing backend type code. It is all in
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index c5ec252a17a..6c2ae1750ec 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2332,23 +2332,6 @@ add_friends (type, name, friend_type)
}
}
-/* Set up a cross reference so that type TYPE will make member function
- CTYPE::DECL a friend when CTYPE is finally defined. For more than
- one, set up a cross reference so that functions with the name DECL
- and type CTYPE know that they are friends of TYPE. */
-static void
-xref_friend (type, decl, ctype)
- tree type, decl, ctype;
-{
- tree friend_decl = TYPE_NAME (ctype);
- tree t = 0;
-
- SET_DECL_WAITING_FRIENDS (friend_decl,
- tree_cons (type, t,
- DECL_WAITING_FRIENDS (friend_decl)));
- TREE_TYPE (DECL_WAITING_FRIENDS (friend_decl)) = decl;
-}
-
/* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already
been defined, we make all of its member functions friends of
TYPE. If not, we make it a pending friend, which can later be added
@@ -2469,24 +2452,14 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
/* Get the class they belong to. */
tree ctype = IDENTIFIER_TYPE_VALUE (cname);
+ tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
- /* This class is defined, use its methods now. */
- if (TYPE_SIZE (ctype))
- {
- tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
- if (fields)
- add_friends (current_class_type, declarator, ctype);
- else
- error ("method `%s' is not a member of class `%s'",
- IDENTIFIER_POINTER (declarator),
- IDENTIFIER_POINTER (cname));
- }
+ if (fields)
+ add_friends (current_class_type, declarator, ctype);
else
- /* Note: DECLARATOR actually has more than one; in this
- case, we're making sure that fns with the name DECLARATOR
- and type CTYPE know they are friends of the current
- class type. */
- xref_friend (current_class_type, declarator, ctype);
+ error ("method `%s' is not a member of class `%s'",
+ IDENTIFIER_POINTER (declarator),
+ IDENTIFIER_POINTER (cname));
decl = void_type_node;
}
}
@@ -2561,49 +2534,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
}
return decl;
}
-
-/* TYPE has now been defined. It may, however, have a number of things
- waiting make make it their friend. We resolve these references
- here. */
-void
-embrace_waiting_friends (type)
- tree type;
-{
- tree decl = TYPE_NAME (type);
- tree waiters;
-
- if (TREE_CODE (decl) != TYPE_DECL)
- return;
-
- for (waiters = DECL_WAITING_FRIENDS (decl); waiters;
- waiters = TREE_CHAIN (waiters))
- {
- tree waiter = TREE_PURPOSE (waiters);
- tree decl = TREE_TYPE (waiters);
- tree name = decl ? (TREE_CODE (decl) == IDENTIFIER_NODE
- ? decl : DECL_NAME (decl)) : NULL_TREE;
- if (name)
- {
- /* @@ There may be work to be done since we have not verified
- @@ consistency between original and friend declarations
- @@ of the functions waiting to become friends. */
- tree field = lookup_fnfields (TYPE_BINFO (type), name, 0);
- if (field)
- if (decl == name)
- add_friends (waiter, name, type);
- else
- add_friend (waiter, decl);
- else
- error_with_file_and_line (DECL_SOURCE_FILE (TYPE_NAME (waiter)),
- DECL_SOURCE_LINE (TYPE_NAME (waiter)),
- "no method `%s' defined in class `%s' to be friend",
- IDENTIFIER_POINTER (DECL_NAME (TREE_TYPE (waiters))),
- TYPE_NAME_STRING (type));
- }
- else
- make_friend_class (type, waiter);
- }
-}
/* Common subroutines of build_new and build_vec_delete. */
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 49e7dd25924..a75344bbea1 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -254,7 +254,7 @@ empty_parms ()
/* %type <itype> try_for_typename */
%type <ttype> condition xcond paren_cond_or_null
%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
-%type <ttype> qualified_type_name complete_type_name notype_identifier
+%type <ttype> 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_specifier_seq
@@ -2854,23 +2854,48 @@ after_type_declarator:
| direct_after_type_declarator
;
-qualified_type_name:
+complete_type_name:
type_name %prec EMPTY
{
- $$ = identifier_typedecl_value ($1);
- /* Remember that this name has been used in the class
- definition, as per [class.scope0] */
- if (current_class_type
- && TYPE_BEING_DEFINED (current_class_type)
- && ! IDENTIFIER_TEMPLATE ($1)
- && ! IDENTIFIER_CLASS_VALUE ($1))
+ if (TREE_CODE ($1) == IDENTIFIER_NODE)
+ {
+ if (current_class_type
+ && TYPE_BEING_DEFINED (current_class_type)
+ && ! TREE_MANGLED ($1)
+ && ! IDENTIFIER_CLASS_VALUE ($1))
+ {
+ /* Be sure to get an inherited typedef. */
+ $$ = lookup_name ($1, 1);
+ /* Remember that this name has been used in the class
+ definition, as per [class.scope0] */
+ pushdecl_class_level ($$);
+ }
+ else
+ $$ = identifier_typedecl_value ($1);
+ }
+ else
+ $$ = $1;
+ }
+ | global_scope type_name
+ {
+ if (TREE_CODE ($2) == IDENTIFIER_NODE)
{
- /* Be sure to get an inherited typedef. */
- $$ = lookup_name ($1, 1);
- pushdecl_class_level ($$);
+ if (current_class_type
+ && TYPE_BEING_DEFINED (current_class_type)
+ && ! TREE_MANGLED ($2)
+ && ! IDENTIFIER_CLASS_VALUE ($2))
+ /* Be sure to get an inherited typedef. */
+ $$ = lookup_name ($2, 1);
+ else
+ $$ = identifier_typedecl_value ($2);
}
+ else
+ $$ = $2;
+ got_scope = NULL_TREE;
}
| nested_type
+ | global_scope nested_type
+ { $$ = $2; }
;
nested_type:
@@ -3016,15 +3041,26 @@ nested_name_specifier_1:
{ goto failed_scope; } */
;
-complete_type_name:
- qualified_type_name
- | global_scope qualified_type_name
- { $$ = $2; }
- ;
-
complex_type_name:
- nested_type
- | global_scope qualified_type_name
+ global_scope type_name
+ {
+ if (TREE_CODE ($2) == IDENTIFIER_NODE)
+ {
+ if (current_class_type
+ && TYPE_BEING_DEFINED (current_class_type)
+ && ! TREE_MANGLED ($2)
+ && ! IDENTIFIER_CLASS_VALUE ($2))
+ /* Be sure to get an inherited typedef. */
+ $$ = lookup_name ($2, 1);
+ else
+ $$ = identifier_typedecl_value ($2);
+ }
+ else
+ $$ = $2;
+ got_scope = NULL_TREE;
+ }
+ | nested_type
+ | global_scope nested_type
{ $$ = $2; }
;
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 97160ad1c48..2f1b0c307ef 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -2034,13 +2034,13 @@ get_matching_virtual (binfo, fndecl, dtorp)
}
if (TYPE_READONLY (d) > TYPE_READONLY (b))
{
- cp_error ("return type of `%#D' adds const", fndecl);
+ cp_error_at ("return type of `%#D' adds const", fndecl);
cp_error_at (" overriding definition as `%#D'",
tmp);
}
else if (TYPE_VOLATILE (d) > TYPE_VOLATILE (b))
{
- cp_error ("return type of `%#D' adds volatile",
+ cp_error_at ("return type of `%#D' adds volatile",
fndecl);
cp_error_at (" overriding definition as `%#D'",
tmp);
@@ -2051,11 +2051,11 @@ get_matching_virtual (binfo, fndecl, dtorp)
{
error ("invalid covariant return type (must use pointer or reference)");
cp_error_at (" overriding `%#D'", tmp);
- cp_error (" with `%#D'", fndecl);
+ cp_error_at (" with `%#D'", fndecl);
}
else if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE)
{
- cp_error ("conflicting return type specified for virtual function `%#D'", fndecl);
+ cp_error_at ("conflicting return type specified for virtual function `%#D'", fndecl);
cp_error_at (" overriding definition as `%#D'", tmp);
SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 0c47de9d795..5a3d2fb6724 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -643,13 +643,15 @@ comptypes (type1, type2, strict)
if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
return 1;
-#ifdef COMP_TYPE_ATTRIBUTES
+ /* ??? COMP_TYPE_ATTRIBUTES is currently useless for variables as each
+ attribute is its own main variant (`val' will remain 0). */
+#ifndef COMP_TYPE_ATTRIBUTES
+#define COMP_TYPE_ATTRIBUTES(t1,t2) 1
+#endif
+
+ /* 1 if no need for warning yet, 2 if warning cause has been seen. */
if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2)))
return 0;
-#else
- /* 1 if no need for warning yet, 2 if warning cause has been seen. */
- attrval = 1;
-#endif
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
val = 0;
@@ -1110,10 +1112,10 @@ self_promoting_args_p (parms)
if (TREE_CHAIN (t) == 0 && type != void_type_node)
return 0;
- if (TYPE_MAIN_VARIANT (type) == float_type_node)
+ if (type == 0)
return 0;
- if (type == 0)
+ if (TYPE_MAIN_VARIANT (type) == float_type_node)
return 0;
if (C_PROMOTING_INTEGER_TYPE_P (type))
@@ -1141,6 +1143,14 @@ unsigned_type (type)
return long_unsigned_type_node;
if (type1 == long_long_integer_type_node)
return long_long_unsigned_type_node;
+ if (type1 == intDI_type_node)
+ return unsigned_intDI_type_node;
+ if (type1 == intSI_type_node)
+ return unsigned_intSI_type_node;
+ if (type1 == intHI_type_node)
+ return unsigned_intHI_type_node;
+ if (type1 == intQI_type_node)
+ return unsigned_intQI_type_node;
return type;
}
@@ -1161,6 +1171,14 @@ signed_type (type)
return long_integer_type_node;
if (type1 == long_long_unsigned_type_node)
return long_long_integer_type_node;
+ if (type1 == unsigned_intDI_type_node)
+ return intDI_type_node;
+ if (type1 == unsigned_intSI_type_node)
+ return intSI_type_node;
+ if (type1 == unsigned_intHI_type_node)
+ return intHI_type_node;
+ if (type1 == unsigned_intQI_type_node)
+ return intQI_type_node;
return type;
}
@@ -1188,6 +1206,8 @@ signed_or_unsigned_type (unsignedp, type)
return type;
}
+/* Compute the value of the `sizeof' operator. */
+
tree
c_sizeof (type)
tree type;
@@ -4251,6 +4271,7 @@ build_unary_op (code, xarg, noconvert)
return error_mark_node;
}
+#if 0
/* If CONVERSIONS is a conversion expression or a nested sequence of such,
convert ARG with the same conversions in the same order
and return the result. */
@@ -4277,6 +4298,7 @@ convert_sequence (conversions, arg)
return arg;
}
}
+#endif
/* Apply unary lvalue-demanding operator CODE to the expression ARG
for certain kinds of expressions which are not really lvalues
@@ -4444,10 +4466,9 @@ mark_addressable (exp)
return 1;
}
case VAR_DECL:
- if (TREE_STATIC (x)
- && TREE_READONLY (x)
+ if (TREE_STATIC (x) && TREE_READONLY (x)
&& DECL_RTL (x) != 0
- && ! decl_in_memory_p (x))
+ && ! DECL_IN_MEMORY_P (x))
{
/* We thought this would make a good constant variable,
but we were wrong. */