+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.
+ (finish_struct_1): Call it.
+
+ * cp-tree.h: Declare warn_sign_compare.
+
+ * typeck.c (build_binary_op_nodefault): Check warn_sign_compare
+ rather than extra_warnings to decide whether to warn about
+ comparison of signed and unsigned.
+
+ * decl2.c (lang_decode_option): Handle warn_sign_compare. -Wall
+ implies -Wsign-compare. -Wall doesn't imply -W.
+
+Wed Feb 7 15:27:57 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_component_ref): Fix to handle anon unions in base
+ classes as well.
+
+Wed Feb 7 14:29:12 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * class.c (resolves_to_fixed_type_p): Delete code dealing with
+ a WITH_CLEANUP_EXPR, since we don't generate them any more.
+ * cvt.c (build_up_reference): Likewise.
+ * decl.c (grok_reference_init): Likewise.
+ (cp_finish_decl): Likewise.
+ * error.c (dump_expr): Likewise.
+ * tree.c (real_lvalue_p): Likewise.
+ (lvalue_p): Likewise.
+ (build_cplus_new): Likewise.
+ (unsave_expr_now): Likewise.
+ * typeck.c (unary_complex_lvalue, build_modify_expr,
+ c_expand_return): Likewise.
+
+Tue Feb 6 13:39:22 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Make the C++ front-end pay attention to attributes for structures.
+ * class.c (finish_struct): New argument ATTRIBUTES, passed down into
+ finish_struct_1.
+ (finish_struct_1): New argument ATTRIBUTES; call cplus_decl_attributes.
+ Take out old round_up_size use and setting the DECL_ALIGN possibly
+ using it. Take out setting of TYPE_ALIGN to round_up_size, which
+ can override what the attribute set.
+ * cp-tree.h (finish_struct): Update prototype.
+ * parse.y (template_instantiate_once): Pass a NULL_TREE for the
+ attributes to finish_struct.
+ (structsp): For a CLASS decl, add maybe_attribute to rule and pass that
+ value down into finish_struct.
+ * Makefile.in (CONFLICTS): Switch to 7 shift/reduce conflicts.
+
+Tue Feb 6 13:12:15 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * decl.c (poplevel): Re-word dead for local handling.
+ (pushdecl): Remove useless DECL_DEAD_FOR_LOCAL test.
+ (cp_finish_decl): If is_for_scope, check for duplicates so
+ we can disable is_for_scope. Otherwise, preserve_temp_slots.
+
+ * lex.c (do_identifier): Use global binding in preference of
+ dead for local variable.
+
+Mon Feb 5 17:46:46 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (initializing_context): Handle anon union changes, the
+ context where fields of anon unions can be initialized now has to be
+ found by walking up the TYPE_CONTEXT chain.
+
+Fri Feb 2 14:54:04 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * decl.c (start_decl): #ifdef out code to set DECL_COMMON
+ if ASM_OUTPUT{,_ALIGNED}_BSS is defined.
+ (obscure_complex_init): If bss is supported, always set
+ DECL_INITIAL to error_mark_node.
+
+Thu Feb 1 16:19:56 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (is_friend): Make sure there's a context before we see if
+ it's an aggr type.
+
+Thu Feb 1 15:44:53 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (is_friend): Classes are not friendly with nested classes.
+
+Thu Feb 1 15:27:37 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * lex.c (check_newline): Pass last character read to HANDLE_PRAGMA,
+ and record its result.
+
Thu Feb 1 09:27:01 1996 Mike Stump <mrs@cygnus.com>
* class.c (finish_struct_anon): Switch around code to not move anon
Tue Sep 7 20:03:33 1993 Jason Merrill (jason@deneb.cygnus.com)
* cp-decl.c: Allow references and template type parameters as well
-
-Local Variables:
-eval: (auto-fill-mode)
-left-margin: 8
-fill-column: 76
-End:
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
`echo $(PARSE_C) | sed 's,^\./,,'`
-CONFLICTS = expect 5 shift/reduce conflicts and 38 reduce/reduce conflicts.
+CONFLICTS = expect 7 shift/reduce conflicts and 38 reduce/reduce conflicts.
$(PARSE_H) : $(PARSE_C)
$(PARSE_C) : $(srcdir)/parse.y
@echo $(CONFLICTS)
}
}
+/* If this declaration supersedes the declaration of
+ a method declared virtual in the base class, then
+ mark this field as being virtual as well. */
+
+void
+fixup_virtual (decl, ctype)
+ tree decl, ctype;
+{
+ tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
+ int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+ int virtualp = DECL_VIRTUAL_P (decl);
+
+ for (i = 0; i < n_baselinks; i++)
+ {
+ tree base_binfo = TREE_VEC_ELT (binfos, i);
+ if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))
+ || flag_all_virtual == 1)
+ {
+ tree tmp = get_matching_virtual
+ (base_binfo, decl,
+ DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
+ if (tmp)
+ {
+ /* If this function overrides some virtual in some base
+ class, then the function itself is also necessarily
+ virtual, even if the user didn't explicitly say so. */
+ DECL_VIRTUAL_P (decl) = 1;
+
+ /* The TMP we really want is the one from the deepest
+ baseclass on this path, taking care not to
+ duplicate if we have already found it (via another
+ path to its virtual baseclass. */
+ if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
+ {
+ cp_error_at ("method `%D' may not be declared static",
+ decl);
+ cp_error_at ("(since `%D' declared virtual in base class.)",
+ tmp);
+ break;
+ }
+ virtualp = 1;
+
+ {
+ /* The argument types may have changed... */
+ tree type = TREE_TYPE (decl);
+ tree argtypes = TYPE_ARG_TYPES (type);
+ tree base_variant = TREE_TYPE (TREE_VALUE (argtypes));
+ tree raises = TYPE_RAISES_EXCEPTIONS (type);
+
+ argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))),
+ TREE_CHAIN (argtypes));
+ /* But the return type has not. */
+ type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes);
+ if (raises)
+ type = build_exception_variant (type, raises);
+ TREE_TYPE (decl) = type;
+ DECL_VINDEX (decl)
+ = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl));
+ }
+ break;
+ }
+ }
+ }
+ if (virtualp)
+ {
+ if (DECL_VINDEX (decl) == NULL_TREE)
+ DECL_VINDEX (decl) = error_mark_node;
+ IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
+ }
+}
+
/* Warn about hidden virtual functions that are not overridden in t. */
void
warn_hidden (t)
TREE_LIST elements, whose TREE_PURPOSE field tells what access
the list has, and the TREE_VALUE slot gives the actual fields.
+ ATTRIBUTES is the set of decl attributes to be applied, if any.
+
If flag_all_virtual == 1, then we lay all functions into
the virtual function table, as though they were declared
virtual. Constructors do not lay down in the virtual function table.
or otherwise in a type-consistent manner. */
tree
-finish_struct_1 (t, warn_anon)
- tree t;
+finish_struct_1 (t, attributes, warn_anon)
+ tree t, attributes;
int warn_anon;
{
int old;
- int round_up_size = 1;
-
tree name = TYPE_IDENTIFIER (t);
enum tree_code code = TREE_CODE (t);
tree fields = TYPE_FIELDS (t);
TYPE_SIZE (t) = NULL_TREE;
CLASSTYPE_GOT_SEMICOLON (t) = 0;
+ cplus_decl_attributes (t, attributes, NULL_TREE);
+
#if 0
/* This is in general too late to do this. I moved the main case up to
left_curly, what else needs to move? */
DECL_SAVED_INSNS (x) = NULL_RTX;
DECL_FIELD_SIZE (x) = 0;
+ fixup_virtual (x, t);
+
/* The name of the field is the original field name
Save this in auxiliary field for later overloading. */
if (DECL_VINDEX (x)
if (width == 0)
{
#ifdef EMPTY_FIELD_BOUNDARY
- /* field size 0 => mark following field as "aligned" */
- if (TREE_CHAIN (x))
- DECL_ALIGN (TREE_CHAIN (x))
- = MAX (DECL_ALIGN (TREE_CHAIN (x)), EMPTY_FIELD_BOUNDARY);
- /* field of size 0 at the end => round up the size. */
- else
- round_up_size = EMPTY_FIELD_BOUNDARY;
+ DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
#endif
#ifdef PCC_BITFIELD_TYPE_MATTERS
DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
TYPE_FIELDS (t) = fields;
- /* If there's a :0 field at the end, round the size to the
- EMPTY_FIELD_BOUNDARY. */
- TYPE_ALIGN (t) = round_up_size;
-
/* Pass layout information about base classes to layout_type, if any. */
if (n_baseclasses)
{
}
tree
-finish_struct (t, list_of_fieldlists, warn_anon)
- tree t;
- tree list_of_fieldlists;
+finish_struct (t, list_of_fieldlists, attributes, warn_anon)
+ tree t, list_of_fieldlists, attributes;
int warn_anon;
{
tree fields = NULL_TREE;
return t;
}
else
- return finish_struct_1 (t, warn_anon);
+ return finish_struct_1 (t, attributes, warn_anon);
}
\f
/* Return non-zero if the effective type of INSTANCE is static.
case COMPONENT_REF:
return resolves_to_fixed_type_p (TREE_OPERAND (instance, 1), nonnull);
- case WITH_CLEANUP_EXPR:
- if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
- return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
- /* fall through... */
case VAR_DECL:
case FIELD_DECL:
if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
/* For a UNSAVE_EXPR, operand 0 is the value to unsave. By unsave, we
mean that all _EXPRs such as TARGET_EXPRs, SAVE_EXPRs,
- WITH_CLEANUP_EXPRs, CALL_EXPRs and RTL_EXPRs, that are protected
+ CALL_EXPRs and RTL_EXPRs, that are protected
from being evaluated more than once should be reset so that a new
expand_expr call of this expr will cause those to be re-evaluated.
This is useful when we want to reuse a tree in different places,
extern int warn_missing_braces;
+/* Warn about comparison of signed and unsigned values. */
+
+extern int warn_sign_compare;
+
/* Warn about a subscript that has type char. */
extern int warn_char_subscripts;
#endif
/* In a VAR_DECL for a variable declared in a for statement,
- this is the shadowed variable. */
+ this is the shadowed (local) variable. */
#define DECL_SHADOWED_FOR_VAR(NODE) DECL_RESULT(NODE)
/* Points back to the decl which caused this lang_decl to be allocated. */
extern void add_method PROTO((tree, tree *, tree));
extern tree get_vfield_offset PROTO((tree));
extern void duplicate_tag_error PROTO((tree));
-extern tree finish_struct PROTO((tree, tree, int));
+extern tree finish_struct PROTO((tree, tree, tree, int));
extern int resolves_to_fixed_type_p PROTO((tree, int *));
extern void init_class_processing PROTO((void));
extern void pushclass PROTO((tree, int));
build_up_reference (type, TREE_OPERAND (targ, 1),
LOOKUP_PROTECT, checkconst));
- case WITH_CLEANUP_EXPR:
- return build (WITH_CLEANUP_EXPR, type,
- build_up_reference (type, TREE_OPERAND (targ, 0),
- LOOKUP_PROTECT, checkconst),
- 0, TREE_OPERAND (targ, 2));
-
case BIND_EXPR:
arg = TREE_OPERAND (targ, 1);
if (arg == NULL_TREE)
if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
{
temp = build_cplus_new (argtype, targ, 1);
- if (TREE_CODE (temp) == WITH_CLEANUP_EXPR)
- rval = build (WITH_CLEANUP_EXPR, type,
- build1 (ADDR_EXPR, type, TREE_OPERAND (temp, 0)),
- 0, TREE_OPERAND (temp, 2));
- else
- rval = build1 (ADDR_EXPR, type, temp);
+ rval = build1 (ADDR_EXPR, type, temp);
goto done;
}
else if (flags&INDIRECT_BIND)
/* This is set for a namespace binding level. */
unsigned namespace_p : 1;
- /* True if this level is that of a for-statement. */
+ /* True if this level is that of a for-statement where we need to
+ worry about ambiguous (traditional or ANSI) scope rules. */
unsigned is_for_scope : 1;
/* One bit left for this word. */
/* Clear out the meanings of the local variables of this level. */
- for (link = current_binding_level->dead_vars_from_for;
- link != NULL_TREE; link = TREE_CHAIN (link))
- {
- if (DECL_DEAD_FOR_LOCAL (link))
- {
- tree id = DECL_NAME (link);
- if (IDENTIFIER_LOCAL_VALUE (id) == link)
- IDENTIFIER_LOCAL_VALUE (id) = DECL_SHADOWED_FOR_VAR (link);
- }
- }
-
if (current_binding_level->is_for_scope && flag_new_for_scope == 1)
{
+ struct binding_level *outer = current_binding_level->level_chain;
for (link = decls; link; link = TREE_CHAIN (link))
{
if (TREE_CODE (link) == VAR_DECL)
DECL_DEAD_FOR_LOCAL (link) = 1;
}
+
+ /* Save declarations made in a 'for' statement so we can support pre-ANSI
+ 'for' scoping semantics. */
+
+ for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
+ {
+ tree id = TREE_PURPOSE (link);
+ tree decl = IDENTIFIER_LOCAL_VALUE (id);
+
+ /* In this case keep the dead for-decl visible,
+ but remember what (if anything) it shadowed. */
+ DECL_SHADOWED_FOR_VAR (decl) = TREE_VALUE (link);
+ TREE_CHAIN (decl) = outer->dead_vars_from_for;
+ outer->dead_vars_from_for = decl;
+ }
}
- else
+ else /* Not special for scope. */
{
for (link = decls; link; link = TREE_CHAIN (link))
{
IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE;
}
}
- }
- /* Restore all name-meanings of the outer levels
- that were shadowed by this level. */
+ /* Restore all name-meanings of the outer levels
+ that were shadowed by this level. */
- if (current_binding_level->is_for_scope && flag_new_for_scope == 1)
- {
- struct binding_level *outer = current_binding_level->level_chain;
- for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
+ for (link = current_binding_level->shadowed;
+ link; link = TREE_CHAIN (link))
+ IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+
+ /* We first restore the regular decls and *then* the dead_vars_from_for
+ to handle this case:
+
+ int i; // i#1
+ {
+ for (int i; ; ) { ...} // i#2
+ int i; // i#3
+ } // we are here
+
+ In this case, we want remove the binding for i#3, restoring
+ that of i#2. Then we want to remove the binding for i#2,
+ and restore that of i#1. */
+
+ link = current_binding_level->dead_vars_from_for;
+ for (; link != NULL_TREE; link = TREE_CHAIN (link))
{
- tree id = TREE_PURPOSE (link);
- tree decl = IDENTIFIER_LOCAL_VALUE (id);
- if (DECL_DEAD_FOR_LOCAL (decl))
- DECL_SHADOWED_FOR_VAR (decl) = TREE_VALUE (link);
- else
- IDENTIFIER_LOCAL_VALUE (id) = TREE_VALUE (link);
+ tree id = DECL_NAME (link);
+ if (IDENTIFIER_LOCAL_VALUE (id) == link)
+ IDENTIFIER_LOCAL_VALUE (id) = DECL_SHADOWED_FOR_VAR (link);
}
- /* Save declarations made in a 'for' statement so we can support pre-ANSI
- 'for' scoping semantics. */
-
- /* We append the current names of for-variables to those from previous
- declarations, so that when we get around to do an poplevel
- on the OUTER level, we restore the any shadowed readl bindings.
- Note that the new names are put first on the combined list,
- so they get to be restored first. This is important if there are
- two for-loops using the same for-variable in the same block.
- The binding we really want restored is whatever binding was shadowed
- by the *first* for-variable, not the binding shadowed by the
- second for-variable (which would be the first for-variable). */
- outer->dead_vars_from_for
- = chainon (current_binding_level->names, outer->dead_vars_from_for);
- }
- else
- {
- for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
- IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+ for (link = current_binding_level->class_shadowed;
+ link; link = TREE_CHAIN (link))
+ IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+ for (link = current_binding_level->type_shadowed;
+ link; link = TREE_CHAIN (link))
+ IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
}
- for (link = current_binding_level->class_shadowed;
- link; link = TREE_CHAIN (link))
- IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
- for (link = current_binding_level->type_shadowed;
- link; link = TREE_CHAIN (link))
- IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
/* If the level being exited is the top level of a function,
check over all the labels. */
{
file = DECL_SOURCE_FILE (t);
line = DECL_SOURCE_LINE (t);
- if (TREE_CODE (x) == VAR_DECL && DECL_DEAD_FOR_LOCAL (x))
- ; /* This is OK. */
- else if (TREE_CODE (t) == PARM_DECL)
+ if (TREE_CODE (t) == PARM_DECL)
{
if (DECL_CONTEXT (t) == NULL_TREE)
fatal ("parse errors have confused me too much");
tem = decl;
else
tem = pushdecl (decl);
-
+
+#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
/* Tell the back-end to use or not use .common as appropriate. If we say
-fconserve-space, we want this to save space, at the expense of wrong
semantics. If we say -fno-conserve-space, we want this to produce
the linker can't match it with storage from other files, and we may
save some disk space. */
DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
+#endif
if (TREE_CODE (decl) == TEMPLATE_DECL)
{
don't get burned by "aggressive" cleanup policy. */
if (TYPE_NEEDS_DESTRUCTOR (subtype))
{
- if (TREE_CODE (init) == WITH_CLEANUP_EXPR)
+ if (TREE_CODE (tmp) == ADDR_EXPR)
+ tmp = TREE_OPERAND (tmp, 0);
+ if (TREE_CODE (tmp) == TARGET_EXPR)
{
- *cleanupp = TREE_OPERAND (init, 2);
- TREE_OPERAND (init, 2) = error_mark_node;
- }
- else
- {
- if (TREE_CODE (tmp) == ADDR_EXPR)
- tmp = TREE_OPERAND (tmp, 0);
- if (TREE_CODE (tmp) == TARGET_EXPR)
- {
- *cleanupp = build_delete
- (build_pointer_type (subtype),
- build_unary_op (ADDR_EXPR, TREE_OPERAND (tmp, 0), 0),
- integer_two_node, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
- TREE_OPERAND (tmp, 2) = error_mark_node;
- }
+ *cleanupp = build_delete
+ (build_pointer_type (subtype),
+ build_unary_op (ADDR_EXPR, TREE_OPERAND (tmp, 0), 0),
+ integer_two_node, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
+ TREE_OPERAND (tmp, 2) = error_mark_node;
}
}
return NULL_TREE;
}
+#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
if (toplevel_bindings_p () && ! DECL_COMMON (decl))
DECL_INITIAL (decl) = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE,
NULL_TREE);
else
+#endif
DECL_INITIAL (decl) = error_mark_node;
return init;
if (!DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type))
{
int yes = suspend_momentary ();
-
- /* If INIT comes from a functional cast, use the cleanup
- we built for that. Otherwise, make our own cleanup. */
- if (init && TREE_CODE (init) == WITH_CLEANUP_EXPR
- && comptypes (TREE_TYPE (decl), TREE_TYPE (init), 1))
- {
- cleanup = TREE_OPERAND (init, 2);
- init = TREE_OPERAND (init, 0);
- current_binding_level->have_cleanups = 1;
- }
- else
- cleanup = maybe_build_cleanup (decl);
+ cleanup = maybe_build_cleanup (decl);
resume_momentary (yes);
}
}
}
}
+ if (current_binding_level->is_for_scope)
+ {
+ struct binding_level *outer = current_binding_level->level_chain;
+
+ /* Check to see if the same name is already bound at
+ the outer level, either because it was directly declared,
+ or because a dead for-decl got preserved. In either case,
+ the code would not have been valid under the traditional
+ scope rules, so clear is_for_scope for the
+ current_binding_level.
+
+ Otherwise, we need to preserve the temp slot for decl
+ to last into the outer binding level. */
+
+ int handling_dead_for_vars = 0;
+ tree link = outer->names;
+ for (; ; link = TREE_CHAIN (link))
+ {
+ if (link == NULL && handling_dead_for_vars == 0)
+ {
+ link = outer->dead_vars_from_for;
+ handling_dead_for_vars = 1;
+ }
+ if (link == NULL)
+ {
+ if (DECL_RTL (decl) && GET_CODE (DECL_RTL (decl)) == MEM)
+ preserve_temp_slots (DECL_RTL (decl));
+ break;
+ }
+ if (DECL_NAME (link) == DECL_NAME (decl))
+ {
+ if (handling_dead_for_vars)
+ {
+ tree shadowing
+ = purpose_member (DECL_NAME (decl),
+ current_binding_level->shadowed);
+ if (shadowing && TREE_VALUE (shadowing) == link)
+ TREE_VALUE (shadowing)
+ = DECL_SHADOWED_FOR_VAR (link);
+ }
+ current_binding_level->is_for_scope = 0;
+ break;
+ }
+ }
+ }
+
push_temp_slots ();
push_temp_slots ();
target_temp_slot_level = temp_slot_level;
TREE_VALUE (attrlist));
make_decl_rtl (decl, NULL_PTR, 1);
}
-
- /* If this declaration supersedes the declaration of
- a method declared virtual in the base class, then
- mark this field as being virtual as well. */
- {
- tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
- int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
- for (i = 0; i < n_baselinks; i++)
- {
- tree base_binfo = TREE_VEC_ELT (binfos, i);
- if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))
- || flag_all_virtual == 1)
- {
- tmp = get_matching_virtual (base_binfo, decl,
- flags == DTOR_FLAG);
- if (tmp)
- {
- /* If this function overrides some virtual in some base
- class, then the function itself is also necessarily
- virtual, even if the user didn't explicitly say so. */
- DECL_VIRTUAL_P (decl) = 1;
-
- /* The TMP we really want is the one from the deepest
- baseclass on this path, taking care not to
- duplicate if we have already found it (via another
- path to its virtual baseclass. */
- if (staticp)
- {
- cp_error ("method `%D' may not be declared static",
- decl);
- cp_error_at ("(since `%D' declared virtual in base class.)",
- tmp);
- break;
- }
- virtualp = 1;
-
- {
- /* The argument types may have changed... */
- tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
- tree base_variant = TREE_TYPE (TREE_VALUE (argtypes));
-
- argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))),
- TREE_CHAIN (argtypes));
- /* But the return type has not. */
- type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes);
- if (raises)
- {
- type = build_exception_variant (type, raises);
- raises = TYPE_RAISES_EXCEPTIONS (type);
- }
- TREE_TYPE (decl) = type;
- DECL_VINDEX (decl)
- = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl));
- }
- break;
- }
- }
- }
- }
if (virtualp)
{
+ DECL_VIRTUAL_P (decl) = 1;
if (DECL_VINDEX (decl) == NULL_TREE)
DECL_VINDEX (decl) = error_mark_node;
IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
- if (ctype && CLASSTYPE_VTABLE_NEEDS_WRITING (ctype)
- /* If this function is derived from a template, don't
- make it public. This shouldn't be here, but there's
- no good way to override the interface pragmas for one
- function or class only. Bletch. */
- && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (ctype)) == NULL_TREE
- && (write_virtuals == 2
- || (write_virtuals == 3
- && CLASSTYPE_INTERFACE_KNOWN (ctype))))
- TREE_PUBLIC (decl) = 1;
}
}
return decl;
int warn_missing_braces;
+/* Warn about comparison of signed and unsigned values. */
+
+int warn_sign_compare;
+
/* Warn about *printf or *scanf format/argument anomalies. */
int warn_format;
warn_redundant_decls = setting;
else if (!strcmp (p, "missing-braces"))
warn_missing_braces = setting;
+ else if (!strcmp (p, "sign-compare"))
+ warn_sign_compare = setting;
else if (!strcmp (p, "format"))
warn_format = setting;
else if (!strcmp (p, "conversion"))
; /* cpp handles this one. */
else if (!strcmp (p, "all"))
{
- extra_warnings = setting;
warn_return_type = setting;
warn_unused = setting;
warn_implicit = setting;
warn_format = setting;
warn_parentheses = setting;
warn_missing_braces = setting;
+ warn_sign_compare = setting;
warn_extern_inline = setting;
warn_nonvdtor = setting;
/* We save the value of warn_uninitialized, since if they put
}
break;
- case WITH_CLEANUP_EXPR:
- /* Note that this only works for G++ cleanups. If somebody
- builds a general cleanup, there's no way to represent it. */
- dump_expr (TREE_OPERAND (t, 0), 0);
- break;
-
case TARGET_EXPR:
/* Note that this only works for G++ target exprs. If somebody
builds a general TARGET_EXPR, there's no way to represent that
expand_member_init (build_indirect_ref (base, NULL_PTR), name, init);
}
+/* Find the context in which this FIELD can be initialized. */
+static tree
+initializing_context (field)
+ tree field;
+{
+ tree t = DECL_CONTEXT (field);
+
+ /* Anonymous union members can be initialized in the first enclosing
+ non-anonymous union context. */
+ while (t && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
+ t = TYPE_CONTEXT (t);
+ return t;
+}
+
/* Function to give error message if member initialization specification
is erroneous. FIELD is the member we decided to initialize.
TYPE is the type for which the initialization is being performed.
{
if (field == error_mark_node)
return 0;
- if (field == NULL_TREE || DECL_CONTEXT (field) != type)
+ if (field == NULL_TREE || initializing_context (field) != type)
{
cp_error ("class `%T' does not have any field named `%s'", type,
member_name);
tree context;
if (! declp)
- context = DECL_CONTEXT (TYPE_NAME (supplicant));
+ {
+ /* Are we a nested or local class? If so, we aren't friends
+ with the CONTEXT. */
+ if (IS_AGGR_TYPE (supplicant))
+ context = NULL_TREE;
+ else
+ context = DECL_CONTEXT (TYPE_NAME (supplicant));
+ }
else if (DECL_FUNCTION_MEMBER_P (supplicant))
context = DECL_CLASS_CONTEXT (supplicant);
else
tricks. */
else
{
- ungetc (c, finput);
- HANDLE_PRAGMA (finput);
+ c = HANDLE_PRAGMA (finput, c);
}
#endif
#endif
if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id))
{
tree shadowed = DECL_SHADOWED_FOR_VAR (id);
+ while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
+ && DECL_DEAD_FOR_LOCAL (shadowed))
+ shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
+ if (!shadowed)
+ shadowed = IDENTIFIER_GLOBAL_VALUE (DECL_NAME (id));
if (shadowed)
{
if (!DECL_ERROR_REPORTED (id))
}
left_curly opt.component_decl_list '}'
{
- tree t = finish_struct ($<ttype>3, $5, 0);
+ tree t = finish_struct ($<ttype>3, $5, NULL_TREE, 0);
pop_obstacks ();
end_template_instantiation ($1);
| TYPENAME_KEYWORD complex_type_name
{ $$ = $2; }
/* C++ extensions, merged with C to avoid shift/reduce conflicts */
- | class_head left_curly opt.component_decl_list '}'
+ | class_head left_curly opt.component_decl_list '}' maybe_attribute
{
int semi;
tree id;
/* $$ = $1 from default rule. */;
else
{
- $$ = finish_struct ($$, $3, semi);
+ $$ = finish_struct ($$, $3, $5, semi);
if (semi) note_got_semicolon ($$);
}
return 1;
break;
- case WITH_CLEANUP_EXPR:
- return real_lvalue_p (TREE_OPERAND (ref, 0));
-
/* A currently unresolved scope ref. */
case SCOPE_REF:
my_friendly_abort (103);
return 1;
break;
- case WITH_CLEANUP_EXPR:
- return lvalue_p (TREE_OPERAND (ref, 0));
-
case TARGET_EXPR:
return 1;
Build an encapsulation of the initialization to perform
and return it so that it can be processed by language-independent
- and language-specific expression expanders.
-
- If WITH_CLEANUP_P is nonzero, we build a cleanup for this expression.
- Otherwise, cleanups are not built here. For example, when building
- an initialization for a stack slot, since the called function handles
- the cleanup, we would not want to do it here. */
+ and language-specific expression expanders. */
tree
build_cplus_new (type, init, with_cleanup_p)
tree type;
TREE_SIDE_EFFECTS (rval) = 1;
TREE_ADDRESSABLE (rval) = 1;
-#if 0
- if (with_cleanup_p && TYPE_NEEDS_DESTRUCTOR (type))
- {
- TREE_OPERAND (rval, 2) = error_mark_node;
- rval = build (WITH_CLEANUP_EXPR, type, rval, 0,
- build_delete (build_pointer_type (type),
- build_unary_op (ADDR_EXPR, slot, 0),
- integer_two_node,
- LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0));
- TREE_SIDE_EFFECTS (rval) = 1;
- TREE_ADDRESSABLE (rval) = 1;
- }
-#endif
return rval;
}
}
}
break;
-
- case WITH_CLEANUP_EXPR:
- warning ("WITH_CLEANUP_EXPR reused inside UNSAVE_EXPR");
- RTL_EXPR_RTL (expr) = NULL_RTX;
- break;
}
switch (TREE_CODE_CLASS (code))
}
}
+ /* See if we have to do any conversions so that we pick up the field from the
+ right context. */
if (DECL_FIELD_CONTEXT (field) != basetype)
{
tree context = DECL_FIELD_CONTEXT (field);
+ tree base = context;
+ while (base != basetype && ANON_AGGRNAME_P (TYPE_IDENTIFIER (base)))
+ {
+ base = TYPE_CONTEXT (base);
+ }
+
+ /* Handle base classes here... */
+ if (base != basetype && TYPE_USES_COMPLEX_INHERITANCE (basetype))
+ {
+ tree addr = build_unary_op (ADDR_EXPR, datum, 0);
+ if (integer_zerop (addr))
+ {
+ error ("invalid reference to NULL ptr, use ptr-to-member instead");
+ return error_mark_node;
+ }
+ if (VBASE_NAME_P (DECL_NAME (field)))
+ {
+ /* It doesn't matter which vbase pointer we grab, just
+ find one of them. */
+ tree binfo = get_binfo (base,
+ TREE_TYPE (TREE_TYPE (addr)), 0);
+ addr = convert_pointer_to_real (binfo, addr);
+ }
+ else
+ addr = convert_pointer_to (base, addr);
+ datum = build_indirect_ref (addr, NULL_PTR);
+ my_friendly_assert (datum != error_mark_node, 311);
+ }
+ basetype = base;
+
+ /* Handle things from anon unions here... */
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
{
tree subfield = lookup_anon_field (basetype, context);
}
}
- if (DECL_FIELD_CONTEXT (field) != basetype
- && TYPE_USES_COMPLEX_INHERITANCE (basetype))
- {
- tree addr = build_unary_op (ADDR_EXPR, datum, 0);
- if (integer_zerop (addr))
- {
- error ("invalid reference to NULL ptr, use ptr-to-member instead");
- return error_mark_node;
- }
- if (VBASE_NAME_P (DECL_NAME (field)))
- {
- /* It doesn't matter which vbase pointer we grab, just
- find one of them. */
- tree binfo = get_binfo (DECL_FIELD_CONTEXT (field),
- TREE_TYPE (TREE_TYPE (addr)), 0);
- addr = convert_pointer_to_real (binfo, addr);
- }
- else
- addr = convert_pointer_to (DECL_FIELD_CONTEXT (field), addr);
- datum = build_indirect_ref (addr, NULL_PTR);
- my_friendly_assert (datum != error_mark_node, 311);
- }
ref = fold (build (COMPONENT_REF, TREE_TYPE (field),
break_out_cleanups (datum), field));
resultcode = xresultcode;
}
- if (short_compare && extra_warnings)
+ if (short_compare && warn_sign_compare)
{
int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
return build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result);
}
- if (TREE_CODE (arg) == WITH_CLEANUP_EXPR)
- {
- tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0);
- real_result = build (WITH_CLEANUP_EXPR, TREE_TYPE (real_result),
- real_result, 0, TREE_OPERAND (arg, 2));
- return real_result;
- }
-
if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE
|| TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
if (TREE_CODE (arg) == SAVE_EXPR && TREE_CODE (targ) == INDIRECT_REF)
return build (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
TREE_OPERAND (targ, 0), current_function_decl, NULL);
-
- /* We shouldn't wrap WITH_CLEANUP_EXPRs inside of SAVE_EXPRs, but in case
- we do, here's how to handle it. */
- if (TREE_CODE (arg) == SAVE_EXPR && TREE_CODE (targ) == WITH_CLEANUP_EXPR)
- {
-#if 0
- /* Not really a bug, but something to turn on when testing. */
- compiler_error ("WITH_CLEANUP_EXPR wrapped in SAVE_EXPR");
-#endif
- return unary_complex_lvalue (ADDR_EXPR, targ);
- }
}
/* Don't let anything else be handled specially. */
TREE_OPERAND (newrhs, 2))));
}
}
- else if (modifycode != INIT_EXPR && TREE_CODE (newrhs) == WITH_CLEANUP_EXPR)
- {
- tree cleanup = TREE_OPERAND (newrhs, 2);
- tree slot;
-
- /* Finish up by running cleanups and having the "value" of the lhs. */
- tree exprlist = tree_cons (NULL_TREE, cleanup,
- build_tree_list (NULL_TREE, lhs));
- newrhs = TREE_OPERAND (newrhs, 0);
- if (TREE_CODE (newrhs) == TARGET_EXPR)
- slot = TREE_OPERAND (newrhs, 0);
- else if (TREE_CODE (newrhs) == ADDR_EXPR)
- {
- /* Bad but valid. */
- slot = newrhs;
- warning ("address taken of temporary object");
- }
- else
- my_friendly_abort (118);
-
- /* Copy the value computed in SLOT into LHS. */
- exprlist = tree_cons (NULL_TREE,
- build_modify_expr (lhs, modifycode, slot),
- exprlist);
- /* Evaluate the expression that needs CLEANUP. This will
- compute the value into SLOT. */
- exprlist = tree_cons (NULL_TREE, newrhs, exprlist);
- result = convert (lhstype, build_compound_expr (exprlist));
- }
else
result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
lhstype, lhs, newrhs);
+
TREE_SIDE_EFFECTS (result) = 1;
/* If we got the LHS in a different type for storing in,
{
whats_returned = TREE_OPERAND (whats_returned, 0);
while (TREE_CODE (whats_returned) == NEW_EXPR
- || TREE_CODE (whats_returned) == TARGET_EXPR
- || TREE_CODE (whats_returned) == WITH_CLEANUP_EXPR)
+ || TREE_CODE (whats_returned) == TARGET_EXPR)
{
/* Get the target. */
whats_returned = TREE_OPERAND (whats_returned, 0);