Commit cffa8729 by Mike Stump

82nd Cygnus<->FSF merge

From-SVN: r11328
parent 1144563f
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> Thu Feb 8 15:15:14 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grokfndecl): Move code that looks for virtuals in base * decl.c (grokfndecl): Move code that looks for virtuals in base
classes... classes...
* class.c (fixup_virtual): ... to a new function. * class.c (check_for_override): ... to a new function.
(finish_struct_1): Call it. (finish_struct_1): Call it.
* cp-tree.h: Declare warn_sign_compare. * cp-tree.h: Declare warn_sign_compare.
......
...@@ -2758,7 +2758,7 @@ mark_overriders (fndecl, base_fndecls) ...@@ -2758,7 +2758,7 @@ mark_overriders (fndecl, base_fndecls)
mark this field as being virtual as well. */ mark this field as being virtual as well. */
void void
fixup_virtual (decl, ctype) check_for_override (decl, ctype)
tree decl, ctype; tree decl, ctype;
{ {
tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype)); tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
...@@ -3177,7 +3177,9 @@ finish_struct_1 (t, attributes, warn_anon) ...@@ -3177,7 +3177,9 @@ finish_struct_1 (t, attributes, warn_anon)
DECL_SAVED_INSNS (x) = NULL_RTX; DECL_SAVED_INSNS (x) = NULL_RTX;
DECL_FIELD_SIZE (x) = 0; 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 /* The name of the field is the original field name
Save this in auxiliary field for later overloading. */ Save this in auxiliary field for later overloading. */
...@@ -3198,19 +3200,36 @@ finish_struct_1 (t, attributes, warn_anon) ...@@ -3198,19 +3200,36 @@ finish_struct_1 (t, attributes, warn_anon)
GNU_xref_member (current_class_name, x); GNU_xref_member (current_class_name, x);
/* Handle access declarations. */ /* 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 access
= TREE_PRIVATE (x) ? access_private_node : = TREE_PRIVATE (x) ? access_private_node :
TREE_PROTECTED (x) ? access_protected_node : access_public_node; TREE_PROTECTED (x) ? access_protected_node : access_public_node;
tree fdecl, binfo;
if (last_x) if (last_x)
TREE_CHAIN (last_x) = TREE_CHAIN (x); TREE_CHAIN (last_x) = TREE_CHAIN (x);
else else
fields = TREE_CHAIN (x); 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; continue;
} }
...@@ -3529,6 +3548,7 @@ finish_struct_1 (t, attributes, warn_anon) ...@@ -3529,6 +3548,7 @@ finish_struct_1 (t, attributes, warn_anon)
{ {
/* Here we must cons up a destructor on the fly. */ /* Here we must cons up a destructor on the fly. */
tree dtor = cons_up_default_function (t, name, needs_virtual_dtor != 0); tree dtor = cons_up_default_function (t, name, needs_virtual_dtor != 0);
check_for_override (dtor, t);
/* If we couldn't make it work, then pretend we didn't need it. */ /* If we couldn't make it work, then pretend we didn't need it. */
if (dtor == void_type_node) if (dtor == void_type_node)
...@@ -4125,9 +4145,6 @@ finish_struct_1 (t, attributes, warn_anon) ...@@ -4125,9 +4145,6 @@ finish_struct_1 (t, attributes, warn_anon)
else if (TYPE_NEEDS_CONSTRUCTING (t)) else if (TYPE_NEEDS_CONSTRUCTING (t))
build_class_init_list (t); build_class_init_list (t);
if (! IS_SIGNATURE (t))
embrace_waiting_friends (t);
/* Write out inline function definitions. */ /* Write out inline function definitions. */
do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t)); do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t));
CLASSTYPE_INLINE_FRIENDS (t) = 0; CLASSTYPE_INLINE_FRIENDS (t) = 0;
...@@ -4289,7 +4306,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon) ...@@ -4289,7 +4306,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
/* Check for inconsistent use of this name in the class body. /* Check for inconsistent use of this name in the class body.
Enums, types and static vars have already been checked. */ 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_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL)
{ {
tree name = DECL_NAME (x); tree name = DECL_NAME (x);
......
...@@ -114,3 +114,7 @@ DEFTREECODE (THUNK_DECL, "thunk_decl", "d", 0) ...@@ -114,3 +114,7 @@ DEFTREECODE (THUNK_DECL, "thunk_decl", "d", 0)
/* A namespace declaration. */ /* A namespace declaration. */
DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0) 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)
...@@ -973,6 +973,14 @@ struct lang_decl ...@@ -973,6 +973,14 @@ struct lang_decl
#define TREE_READONLY_DECL_P(NODE) \ #define TREE_READONLY_DECL_P(NODE) \
(TREE_READONLY (NODE) && TREE_CODE_CLASS (TREE_CODE (NODE)) == 'd') (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 /* For FUNCTION_DECLs: return the language in which this decl
was declared. */ was declared. */
#define DECL_LANGUAGE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.language) #define DECL_LANGUAGE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.language)
...@@ -1302,12 +1310,6 @@ extern int flag_new_for_scope; ...@@ -1302,12 +1310,6 @@ extern int flag_new_for_scope;
/* C++: all of these are overloaded! These apply only to TYPE_DECLs. */ /* C++: all of these are overloaded! These apply only to TYPE_DECLs. */
#define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE)) #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 /* The DECL_ACCESS is used to record under which context
special access rules apply. */ special access rules apply. */
...@@ -2124,7 +2126,6 @@ extern tree start_anon_func PROTO((void)); ...@@ -2124,7 +2126,6 @@ extern tree start_anon_func PROTO((void));
/* skip cplus_expand_expr */ /* skip cplus_expand_expr */
extern void init_cplus_expand PROTO((void)); extern void init_cplus_expand PROTO((void));
extern void fixup_result_decl PROTO((tree, struct rtx_def *)); 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)); extern tree unsave_expr_now PROTO((tree));
/* in rtti.c */ /* in rtti.c */
......
...@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */
extern tree get_file_function_name (); extern tree get_file_function_name ();
extern tree cleanups_this_call; extern tree cleanups_this_call;
static void grok_function_init (); static void grok_function_init ();
extern int current_class_depth;
/* A list of virtual function tables we must make sure to write out. */ /* A list of virtual function tables we must make sure to write out. */
tree pending_vtables; tree pending_vtables;
...@@ -1328,11 +1329,20 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist) ...@@ -1328,11 +1329,20 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
flags = 0; 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 if (init
&& TREE_CODE (init) == TREE_LIST && TREE_CODE (init) == TREE_LIST
&& TREE_VALUE (init) == error_mark_node && TREE_VALUE (init) == error_mark_node
&& TREE_CHAIN (init) == NULL_TREE) && TREE_CHAIN (init) == NULL_TREE)
init = NULL_TREE; init = NULL_TREE;
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, value = grokdeclarator (declarator, declspecs, FIELD, init != 0,
raises, NULL_TREE); raises, NULL_TREE);
...@@ -1867,8 +1877,11 @@ grok_function_init (decl, init) ...@@ -1867,8 +1877,11 @@ grok_function_init (decl, init)
if (TREE_CODE (type) == FUNCTION_TYPE) if (TREE_CODE (type) == FUNCTION_TYPE)
cp_error ("initializer specified for non-member function `%D'", decl); 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) else if (DECL_VINDEX (decl) == NULL_TREE)
cp_error ("initializer specified for non-virtual method `%D'", decl); cp_error ("initializer specified for non-virtual method `%D'", decl);
#endif
else if (integer_zerop (init)) else if (integer_zerop (init))
{ {
#if 0 #if 0
...@@ -3404,10 +3417,23 @@ tree ...@@ -3404,10 +3417,23 @@ tree
do_class_using_decl (decl) do_class_using_decl (decl)
tree decl; tree decl;
{ {
tree type; tree name, value;
/* Ignore for now, unimplemented. */ if (TREE_CODE (decl) != SCOPE_REF)
return NULL_TREE; {
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 void
......
...@@ -740,6 +740,13 @@ dump_decl (t, v) ...@@ -740,6 +740,13 @@ dump_decl (t, v)
dump_expr (DECL_INITIAL (t), 0); dump_expr (DECL_INITIAL (t), 0);
break; break;
case USING_DECL:
OB_PUTS ("using ");
dump_type (DECL_INITIAL (t), 0);
OB_PUTS ("::");
OB_PUTID (DECL_NAME (t));
break;
default: default:
sorry ("`%s' not supported by dump_decl", sorry ("`%s' not supported by dump_decl",
tree_code_name[(int) TREE_CODE (t)]); tree_code_name[(int) TREE_CODE (t)]);
......
...@@ -278,19 +278,6 @@ fixup_result_decl (decl, result) ...@@ -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 /* Expand this initialization inline and see if it's simple enough that
it can be done at compile-time. */ it can be done at compile-time. */
......
...@@ -1287,13 +1287,13 @@ Ln: throw value; ...@@ -1287,13 +1287,13 @@ Ln: throw value;
copy value onto heap copy value onto heap
jump throw (Ln, id, address of copy of value on heap) jump throw (Ln, id, address of copy of value on heap)
try { try @{
+Lstart: the start of the main EH region +Lstart: the start of the main EH region
|... ... |... ...
+Lend: the end of the main EH region +Lend: the end of the main EH region
} catch (T o) { @} catch (T o) @{
...1 ...1
} @}
Lresume: Lresume:
nop used to make sure there is something before nop used to make sure there is something before
the next region ends, if there is one the next region ends, if there is one
...@@ -1314,7 +1314,7 @@ Lover: ...@@ -1314,7 +1314,7 @@ Lover:
[ [
[ [
call throw_type_match call throw_type_match
if (eq) { if (eq) @{
] these lines disappear when there is no catch condition ] these lines disappear when there is no catch condition
+Lsregion2: +Lsregion2:
| ...1 | ...1
...@@ -1322,7 +1322,7 @@ Lover: ...@@ -1322,7 +1322,7 @@ Lover:
|Lhandler: handler for the region Lsregion2-Leregion2 |Lhandler: handler for the region Lsregion2-Leregion2
| rethrow (Lresume, same id, same obj); | rethrow (Lresume, same id, same obj);
+Leregion2 +Leregion2
} @}
] there are zero or more of these sections, depending upon how many ] there are zero or more of these sections, depending upon how many
catch clauses there are catch clauses there are
----------------------------- expand_end_all_catch -------------------------- ----------------------------- expand_end_all_catch --------------------------
...@@ -1338,7 +1338,7 @@ Ldone: ...@@ -1338,7 +1338,7 @@ Ldone:
start_all_catch emits labels: Lresume, start_all_catch emits labels: Lresume,
#end example @end example
The __unwind_function takes a pointer to the throw handler, and is 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 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 ...@@ -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: into. The way I normally start is to compile:
void *g; 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 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 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 ...@@ -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 should also be removed, although not doing this is harmless in terms of
semantics. semantics.
#end itemize @end itemize
The above is not meant to be exhaustive, but does include all things I 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. have thought of so far. I am sure other limitations exist.
...@@ -1517,7 +1517,7 @@ pointer, frame pointer, arg pointer and so on. ...@@ -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 The eh archive (~mrs/eh) might be good reading for understanding the Ada
perspective, and some of kenners mindset, and a detailed explanation 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. involved.
Here is a guide to existing backend type code. It is all in Here is a guide to existing backend type code. It is all in
......
...@@ -2332,23 +2332,6 @@ add_friends (type, name, friend_type) ...@@ -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 /* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already
been defined, we make all of its member functions friends of 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 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) ...@@ -2469,24 +2452,14 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
/* Get the class they belong to. */ /* Get the class they belong to. */
tree ctype = IDENTIFIER_TYPE_VALUE (cname); tree ctype = IDENTIFIER_TYPE_VALUE (cname);
tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
/* This class is defined, use its methods now. */ if (fields)
if (TYPE_SIZE (ctype)) add_friends (current_class_type, declarator, 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));
}
else else
/* Note: DECLARATOR actually has more than one; in this error ("method `%s' is not a member of class `%s'",
case, we're making sure that fns with the name DECLARATOR IDENTIFIER_POINTER (declarator),
and type CTYPE know they are friends of the current IDENTIFIER_POINTER (cname));
class type. */
xref_friend (current_class_type, declarator, ctype);
decl = void_type_node; decl = void_type_node;
} }
} }
...@@ -2561,49 +2534,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals) ...@@ -2561,49 +2534,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
} }
return decl; 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. */ /* Common subroutines of build_new and build_vec_delete. */
......
...@@ -254,7 +254,7 @@ empty_parms () ...@@ -254,7 +254,7 @@ empty_parms ()
/* %type <itype> try_for_typename */ /* %type <itype> try_for_typename */
%type <ttype> condition xcond paren_cond_or_null %type <ttype> condition xcond paren_cond_or_null
%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem %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 <ttype> complex_type_name nested_name_specifier_1
%type <itype> nomods_initdecls nomods_initdcl0 %type <itype> nomods_initdecls nomods_initdcl0
%type <ttype> new_initializer new_placement specialization type_specifier_seq %type <ttype> new_initializer new_placement specialization type_specifier_seq
...@@ -2854,23 +2854,48 @@ after_type_declarator: ...@@ -2854,23 +2854,48 @@ after_type_declarator:
| direct_after_type_declarator | direct_after_type_declarator
; ;
qualified_type_name: complete_type_name:
type_name %prec EMPTY type_name %prec EMPTY
{ {
$$ = identifier_typedecl_value ($1); if (TREE_CODE ($1) == IDENTIFIER_NODE)
/* Remember that this name has been used in the class {
definition, as per [class.scope0] */ if (current_class_type
if (current_class_type && TYPE_BEING_DEFINED (current_class_type)
&& TYPE_BEING_DEFINED (current_class_type) && ! TREE_MANGLED ($1)
&& ! IDENTIFIER_TEMPLATE ($1) && ! IDENTIFIER_CLASS_VALUE ($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. */ if (current_class_type
$$ = lookup_name ($1, 1); && TYPE_BEING_DEFINED (current_class_type)
pushdecl_class_level ($$); && ! 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 | nested_type
| global_scope nested_type
{ $$ = $2; }
; ;
nested_type: nested_type:
...@@ -3016,15 +3041,26 @@ nested_name_specifier_1: ...@@ -3016,15 +3041,26 @@ nested_name_specifier_1:
{ goto failed_scope; } */ { goto failed_scope; } */
; ;
complete_type_name:
qualified_type_name
| global_scope qualified_type_name
{ $$ = $2; }
;
complex_type_name: complex_type_name:
nested_type global_scope type_name
| global_scope qualified_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; } { $$ = $2; }
; ;
......
...@@ -2034,13 +2034,13 @@ get_matching_virtual (binfo, fndecl, dtorp) ...@@ -2034,13 +2034,13 @@ get_matching_virtual (binfo, fndecl, dtorp)
} }
if (TYPE_READONLY (d) > TYPE_READONLY (b)) 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'", cp_error_at (" overriding definition as `%#D'",
tmp); tmp);
} }
else if (TYPE_VOLATILE (d) > TYPE_VOLATILE (b)) 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); fndecl);
cp_error_at (" overriding definition as `%#D'", cp_error_at (" overriding definition as `%#D'",
tmp); tmp);
...@@ -2051,11 +2051,11 @@ get_matching_virtual (binfo, fndecl, dtorp) ...@@ -2051,11 +2051,11 @@ get_matching_virtual (binfo, fndecl, dtorp)
{ {
error ("invalid covariant return type (must use pointer or reference)"); error ("invalid covariant return type (must use pointer or reference)");
cp_error_at (" overriding `%#D'", tmp); 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) 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); cp_error_at (" overriding definition as `%#D'", tmp);
SET_IDENTIFIER_ERROR_LOCUS (name, basetype); SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
} }
......
...@@ -643,13 +643,15 @@ comptypes (type1, type2, strict) ...@@ -643,13 +643,15 @@ comptypes (type1, type2, strict)
if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
return 1; 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))) if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2)))
return 0; 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. */ /* 1 if no need for warning yet, 2 if warning cause has been seen. */
val = 0; val = 0;
...@@ -1110,10 +1112,10 @@ self_promoting_args_p (parms) ...@@ -1110,10 +1112,10 @@ self_promoting_args_p (parms)
if (TREE_CHAIN (t) == 0 && type != void_type_node) if (TREE_CHAIN (t) == 0 && type != void_type_node)
return 0; return 0;
if (TYPE_MAIN_VARIANT (type) == float_type_node) if (type == 0)
return 0; return 0;
if (type == 0) if (TYPE_MAIN_VARIANT (type) == float_type_node)
return 0; return 0;
if (C_PROMOTING_INTEGER_TYPE_P (type)) if (C_PROMOTING_INTEGER_TYPE_P (type))
...@@ -1141,6 +1143,14 @@ unsigned_type (type) ...@@ -1141,6 +1143,14 @@ unsigned_type (type)
return long_unsigned_type_node; return long_unsigned_type_node;
if (type1 == long_long_integer_type_node) if (type1 == long_long_integer_type_node)
return long_long_unsigned_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; return type;
} }
...@@ -1161,6 +1171,14 @@ signed_type (type) ...@@ -1161,6 +1171,14 @@ signed_type (type)
return long_integer_type_node; return long_integer_type_node;
if (type1 == long_long_unsigned_type_node) if (type1 == long_long_unsigned_type_node)
return long_long_integer_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; return type;
} }
...@@ -1188,6 +1206,8 @@ signed_or_unsigned_type (unsignedp, type) ...@@ -1188,6 +1206,8 @@ signed_or_unsigned_type (unsignedp, type)
return type; return type;
} }
/* Compute the value of the `sizeof' operator. */
tree tree
c_sizeof (type) c_sizeof (type)
tree type; tree type;
...@@ -4251,6 +4271,7 @@ build_unary_op (code, xarg, noconvert) ...@@ -4251,6 +4271,7 @@ build_unary_op (code, xarg, noconvert)
return error_mark_node; return error_mark_node;
} }
#if 0
/* If CONVERSIONS is a conversion expression or a nested sequence of such, /* If CONVERSIONS is a conversion expression or a nested sequence of such,
convert ARG with the same conversions in the same order convert ARG with the same conversions in the same order
and return the result. */ and return the result. */
...@@ -4277,6 +4298,7 @@ convert_sequence (conversions, arg) ...@@ -4277,6 +4298,7 @@ convert_sequence (conversions, arg)
return arg; return arg;
} }
} }
#endif
/* Apply unary lvalue-demanding operator CODE to the expression ARG /* Apply unary lvalue-demanding operator CODE to the expression ARG
for certain kinds of expressions which are not really lvalues for certain kinds of expressions which are not really lvalues
...@@ -4444,10 +4466,9 @@ mark_addressable (exp) ...@@ -4444,10 +4466,9 @@ mark_addressable (exp)
return 1; return 1;
} }
case VAR_DECL: case VAR_DECL:
if (TREE_STATIC (x) if (TREE_STATIC (x) && TREE_READONLY (x)
&& TREE_READONLY (x)
&& DECL_RTL (x) != 0 && DECL_RTL (x) != 0
&& ! decl_in_memory_p (x)) && ! DECL_IN_MEMORY_P (x))
{ {
/* We thought this would make a good constant variable, /* We thought this would make a good constant variable,
but we were wrong. */ but we were wrong. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment