diff options
author | Mike Stump <mrs@gcc.gnu.org> | 1996-02-20 20:35:10 +0000 |
---|---|---|
committer | Mike Stump <mrs@gcc.gnu.org> | 1996-02-20 20:35:10 +0000 |
commit | cffa87298012df49b1a3bafa4d9d7a66c155378d (patch) | |
tree | 6ee9a4da1768cb23abf74781faddd9d48d5f4b37 /gcc/cp | |
parent | 1144563fbc40c80298e1477c67c0614d1e9a917e (diff) | |
download | gcc-cffa87298012df49b1a3bafa4d9d7a66c155378d.tar.gz |
82nd Cygnus<->FSF merge
From-SVN: r11328
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 101 | ||||
-rw-r--r-- | gcc/cp/class.c | 35 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 4 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 15 | ||||
-rw-r--r-- | gcc/cp/decl.c | 172 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 34 | ||||
-rw-r--r-- | gcc/cp/error.c | 7 | ||||
-rw-r--r-- | gcc/cp/expr.c | 13 | ||||
-rw-r--r-- | gcc/cp/gxxint.texi | 18 | ||||
-rw-r--r-- | gcc/cp/init.c | 82 | ||||
-rw-r--r-- | gcc/cp/parse.y | 76 | ||||
-rw-r--r-- | gcc/cp/search.c | 8 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 41 |
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. */ |