+Fri Apr 28 07:58:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * lex.c (cons_up_default_function): Fix linkage of #pragma
+ implemented functions.
+
+Thu Apr 27 16:56:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (build_overload_name): Simplify and fix repeated type
+ folding.
+
+ * decl.c (grokdeclarator): Prohibit pointers to void or reference
+ members.
+
+Thu Apr 27 09:49:07 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (process_init_constructor): Make sure initializers are
+ fully digested.
+
+Thu Apr 27 01:11:55 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * lex.c (cons_up_default_function): Always defer synthesis.
+
+Thu Apr 27 00:20:37 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl2.c (mark_inline_for_output): Don't play with pending_inline
+ stuff.
+
+Wed Apr 26 17:48:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (user_harshness): New function; like build_type_conversion,
+ but doesn't actually build anything.
+ (compute_conversion_costs): Use it instead of build_type_conversion.
+
+Wed Apr 26 17:11:25 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * typeck.c (build_function_call_real): Improve error message for
+ calling a non-function.
+
+ * method.c (hack_identifier): Lose check for calling a data member.
+
+Wed Apr 26 16:59:13 1995 Mike Stump <mrs@cygnus.com>
+
+ * typeck2.c (build_functional_cast): Remove very old cruft.
+ Seems like good code is generated without it.
+
+Wed Apr 26 00:47:16 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * method.c (do_build_assign_ref): Fix handling of anonymous unions.
+ (do_build_copy_constructor): Ditto.
+
+ * parse.y (simple_stmt, SWITCH): Call {push,pop}_switch.
+
+ * decl.c (push_switch): New function.
+ (pop_switch): Ditto.
+ (define_case_label): Check for jumping over initialization.
+
+ * call.c (build_method_call): Check for an inline function being
+ called before its definition has been seen.
+ * typeck.c (build_function_call_real): Ditto.
+
+ * decl.c (duplicate_decls): Check for a function being redeclared
+ inline after its address has been taken.
+
+ * typeck.c (build_conditional_expr): Handle related class lvalues.
+
+Tue Apr 25 13:20:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * pt.c (do_pending_expansions): Don't expand unused templates.
+
+ * parse.y (component_decl): Accept a lone semicolon.
+
+Tue Apr 25 00:25:56 1995 Jason Merrill <jason@rtl.cygnus.com>
+
+ * call.c (build_method_call): Don't allow an RTL_EXPR to serve as the
+ object parameter anymore.
+
+ * expr.c (cplus_expand_expr): Don't create RTL_EXPRs with no insns.
+
+Mon Apr 24 12:35:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y (simple_stmt, decl case): Clear prefix_attributes.
+ (lang_extdef): Ditto.
+
+ * parse.y (maybe_parmlist): New rule for use in declarators where
+ this could either be a list of expressions or parameters. Calls
+ suspend_momentary before deciding which.
+ (direct_after_type_declarator): Use it.
+ (complex_direct_notype_declarator): Use it.
+
+ * pt.c (tsubst): Propagate attributes const and noreturn.
+
+ * typeck.c (build_modify_expr): If warn_synth, call build_opfncall
+ before doing the default thing.
+
Thu Apr 27 21:49:36 1995 Doug Evans <dje@cygnus.com>
* typeck.c (common_type): Call lookup_attribute instead of
}
int
+user_harshness (type, parmtype, parm)
+ register tree type, parmtype;
+ tree parm;
+{
+ tree conv;
+ tree winner = NULL_TREE;
+ int code;
+
+ {
+ tree typename = build_typename_overload (type);
+ if (lookup_fnfields (TYPE_BINFO (parmtype), typename, 0))
+ return 0;
+ }
+
+ for (conv = lookup_conversions (parmtype); conv; conv = TREE_CHAIN (conv))
+ {
+ struct harshness_code tmp;
+
+ if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv))
+ continue;
+
+ if (tmp = convert_harshness (type, TREE_VALUE (conv), NULL_TREE),
+ tmp.code < USER_CODE)
+ {
+ if (winner)
+ return EVIL_CODE;
+ else
+ {
+ winner = conv;
+ code = tmp.code;
+ }
+ }
+ }
+
+ if (winner)
+ return code;
+
+ return -1;
+}
+
+int
can_convert (to, from)
tree to, from;
{
if (TYPE_LANG_SPECIFIC (actual_type)
&& TYPE_HAS_CONVERSION (actual_type))
{
- tree conv;
- /* Don't issue warnings since we're only groping
- around for the right answer, we haven't yet
- committed to going with this solution. */
- int old_inhibit_warnings = inhibit_warnings;
-
- inhibit_warnings = 1;
- conv = build_type_conversion
- (CALL_EXPR, formal_type, TREE_VALUE (tta), 0);
- inhibit_warnings = old_inhibit_warnings;
-
- if (conv)
+ int extra = user_harshness (formal_type, actual_type);
+
+ if (extra == EVIL_CODE)
+ win += 2;
+ else if (extra >= 0)
{
- if (conv == error_mark_node
- || (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE
- && ! TYPE_READONLY (TREE_VALUE (TREE_VALUE (ttf)))
- && ! lvalue_p (conv)))
- win += 2;
- else
- {
- win++;
- if (TREE_CODE (conv) != CALL_EXPR)
- extra_conversions = 1;
- }
+ win++;
+ extra_conversions = extra;
}
}
}
}
else
{
- if (TREE_CODE (instance) != CALL_EXPR
-#ifdef PCC_STATIC_STRUCT_RETURN
- && TREE_CODE (instance) != RTL_EXPR
-#endif
- )
+ if (TREE_CODE (instance) != CALL_EXPR)
my_friendly_abort (125);
if (TYPE_NEEDS_CONSTRUCTING (basetype))
instance = build_cplus_new (basetype, instance, 0);
#if 1
/* Is it a synthesized method that needs to be synthesized? */
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
- && DECL_SAVED_INSNS (function) == 0
- && ! TREE_ASM_WRITTEN (function)
+ && ! DECL_INITIAL (function)
/* Kludge: don't synthesize for default args. */
&& current_function_decl)
synthesize_method (function);
#endif
+ if (pedantic && DECL_THIS_INLINE (function) && ! DECL_ARTIFICIAL (function)
+ && ! DECL_INITIAL (function) && ! DECL_PENDING_INLINE_INFO (function))
+ cp_pedwarn ("inline function `%#D' called before definition", function);
+
fntype = TREE_TYPE (function);
if (TREE_CODE (fntype) == POINTER_TYPE)
fntype = TREE_TYPE (fntype);
olddecl);
}
}
+
+ if (DECL_THIS_INLINE (newdecl) && ! DECL_THIS_INLINE (olddecl)
+ && TREE_ADDRESSABLE (olddecl))
+ cp_pedwarn ("`%#D' was used before it was declared inline",
+ newdecl);
}
/* These bits are logically part of the type for non-functions. */
else if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
}
}
+struct cp_switch
+{
+ struct binding_level *level;
+ struct cp_switch *next;
+};
+
+static struct cp_switch *switch_stack;
+
+void
+push_switch ()
+{
+ struct cp_switch *p
+ = (struct cp_switch *) oballoc (sizeof (struct cp_switch));
+ p->level = current_binding_level;
+ p->next = switch_stack;
+ switch_stack = p;
+}
+
+void
+pop_switch ()
+{
+ switch_stack = switch_stack->next;
+}
+
/* Same, but for CASE labels. If DECL is NULL_TREE, it's the default. */
/* XXX Note decl is never actually used. (bpk) */
void
tree decl;
{
tree cleanup = last_cleanup_this_contour ();
+ struct binding_level *b = current_binding_level;
+ int identified = 0;
+
if (cleanup)
{
static int explained = 0;
- cp_error_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup));
- error ("where case label appears here");
+ cp_warning_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup));
+ warning ("where case label appears here");
if (!explained)
{
- error ("(enclose actions of previous case statements requiring");
- error ("destructors in their own binding contours.)");
+ warning ("(enclose actions of previous case statements requiring");
+ warning ("destructors in their own binding contours.)");
explained = 1;
}
}
+ for (; b && b != switch_stack->level; b = b->level_chain)
+ {
+ tree new_decls = b->names;
+ for (; new_decls; new_decls = TREE_CHAIN (new_decls))
+ {
+ if (TREE_CODE (new_decls) == VAR_DECL
+ /* Don't complain about crossing initialization
+ of internal entities. They can't be accessed,
+ and they should be cleaned up
+ by the time we get to the label. */
+ && ! DECL_ARTIFICIAL (new_decls)
+ && ((DECL_INITIAL (new_decls) != NULL_TREE
+ && DECL_INITIAL (new_decls) != error_mark_node)
+ || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))))
+ {
+ if (! identified)
+ error ("jump to case label");
+ identified = 1;
+ cp_error_at (" crosses initialization of `%#D'",
+ new_decls);
+ }
+ }
+ }
+
/* After labels, make any new cleanups go into their
own new (temporary) binding contour. */
continue;
}
+ if (TREE_CODE (type) == OFFSET_TYPE
+ && (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE
+ || TREE_CODE (TREE_TYPE (type)) == REFERENCE_TYPE))
+ {
+ cp_error ("cannot declare pointer to `%#T' member",
+ TREE_TYPE (type));
+ type = TREE_TYPE (type);
+ }
+
/* Merge any constancy or volatility into the target type
for the pointer. */
return;
my_friendly_assert (TREE_PERMANENT (decl), 363);
DECL_SAVED_INLINE (decl) = 1;
+#if 0
if (DECL_PENDING_INLINE_INFO (decl) != 0
&& ! DECL_PENDING_INLINE_INFO (decl)->deja_vu)
{
}
DECL_PENDING_INLINE_INFO (decl) = 0;
}
+#endif
saved_inlines = perm_tree_cons (NULL_TREE, decl, saved_inlines);
}
extern int flag_access_control;
int old_ac = flag_access_control;
- tree init = build (RTL_EXPR, type, 0, return_target);
+ tree init = build_decl (VAR_DECL, 0, type);
TREE_ADDRESSABLE (init) = 1;
+ DECL_RTL (init) = return_target;
flag_access_control = 0;
expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
if (TYPE_NEEDS_DESTRUCTOR (type))
{
- init = build (RTL_EXPR, build_reference_type (type), 0,
- XEXP (return_target, 0));
+ init = build_decl (VAR_DECL, 0,
+ build_reference_type (type));
+ DECL_RTL (init) = XEXP (return_target, 0);
+
init = maybe_build_cleanup (convert_from_reference (init));
if (init != NULL_TREE)
expand_expr (init, 0, 0, 0);
@}
@end example
+@section Linkage
+The linkage code in g++ is horribly twisted in order to meet two design goals:
+
+1) Avoid unnecessary emission of inlines and vtables.
+
+2) Support pedantic assemblers like the one in AIX.
+
+To meet the first goal, we defer emission of inlines and vtables until
+the end of the translation unit, where we can decide whether or not they
+are needed, and how to emit them if they are.
+
@node Concept Index, , Free Store, Top
@section Concept Index
if (CLASSTYPE_INTERFACE_KNOWN (type))
{
DECL_INTERFACE_KNOWN (fn) = 1;
- DECL_EXTERNAL (fn) = (CLASSTYPE_INTERFACE_ONLY (type)
- || ! flag_implement_inlines);
- TREE_STATIC (fn) = ! DECL_EXTERNAL (fn);
+ DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type)
+ && flag_implement_inlines);
}
else
DECL_NOT_REALLY_EXTERN (fn) = 1;
+#if 0
/* When on-the-fly synthesis works properly, remove the second and third
conditions here. */
if (flag_keep_inline_functions
store_pending_inline (fn, t);
}
else
+#endif
mark_inline_for_output (fn);
#ifdef DEBUG_DEFAULT_FUNCTIONS
only_one:
- if (! nofold)
+ if (! nofold && ! just_one)
{
- if (! just_one)
- /* Every argument gets counted. */
- typevec[maxtype++] = parmtype;
+ /* Every argument gets counted. */
+ typevec[maxtype++] = parmtype;
- if (TREE_USED (parmtype))
+ if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2])
{
- if (! just_one && parmtype == typevec[maxtype-2])
- nrepeats++;
- else
- {
- if (nrepeats)
- flush_repeats (parmtype);
- if (! just_one && TREE_CHAIN (parmtypes)
- && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes)))
- nrepeats++;
- else
- {
- int tindex = 0;
-
- while (typevec[tindex] != parmtype)
- tindex++;
- OB_PUTC ('T');
- icat (tindex);
- if (tindex > 9)
- OB_PUTC ('_');
- }
- }
+ nrepeats++;
goto next;
}
+
if (nrepeats)
flush_repeats (typevec[maxtype-2]);
- if (! just_one
- /* Only cache types which take more than one character. */
- && (parmtype != TYPE_MAIN_VARIANT (parmtype)
- || (TREE_CODE (parmtype) != INTEGER_TYPE
- && TREE_CODE (parmtype) != REAL_TYPE)))
+
+ if (TREE_USED (parmtype))
+ {
+ flush_repeats (parmtype);
+ goto next;
+ }
+
+ /* Only cache types which take more than one character. */
+ if (parmtype != TYPE_MAIN_VARIANT (parmtype)
+ || (TREE_CODE (parmtype) != INTEGER_TYPE
+ && TREE_CODE (parmtype) != REAL_TYPE))
TREE_USED (parmtype) = 1;
}
return error_mark_node;
}
TREE_USED (current_class_decl) = 1;
- if (yychar == '(')
- if (! ((TYPE_LANG_SPECIFIC (type)
- && TYPE_OVERLOADS_CALL_EXPR (type))
- || (TREE_CODE (type) == REFERENCE_TYPE
- && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
- && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type))))
- && TREE_CODE (type) != FUNCTION_TYPE
- && TREE_CODE (type) != METHOD_TYPE
- && !TYPE_PTRMEMFUNC_P (type)
- && (TREE_CODE (type) != POINTER_TYPE
- || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE
- && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE)))
- {
- error ("component `%s' is not a method",
- IDENTIFIER_POINTER (name));
- return error_mark_node;
- }
+
/* Mark so that if we are in a constructor, and then find that
this field was initialized by a base initializer,
we can emit an error message. */
for (; fields; fields = TREE_CHAIN (fields))
{
tree name, init, t;
- if (TREE_CODE (fields) != FIELD_DECL)
+ tree field = fields;
+
+ if (TREE_CODE (field) != FIELD_DECL)
continue;
- if (DECL_NAME (fields))
+ if (DECL_NAME (field))
{
- if (VFIELD_NAME_P (DECL_NAME (fields)))
+ if (VFIELD_NAME_P (DECL_NAME (field)))
continue;
- if (VBASE_NAME_P (DECL_NAME (fields)))
+ if (VBASE_NAME_P (DECL_NAME (field)))
continue;
/* True for duplicate members. */
- if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
+ if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
continue;
}
- else if ((t = TREE_TYPE (fields)) != NULL_TREE
+ else if ((t = TREE_TYPE (field)) != NULL_TREE
&& TREE_CODE (t) == UNION_TYPE
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
&& TYPE_FIELDS (t) != NULL_TREE)
- fields = largest_union_member (t);
+ field = largest_union_member (t);
else
continue;
- init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields);
+ init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
init = build_tree_list (NULL_TREE, init);
current_member_init_list
- = tree_cons (DECL_NAME (fields), init, current_member_init_list);
+ = tree_cons (DECL_NAME (field), init, current_member_init_list);
}
current_member_init_list = nreverse (current_member_init_list);
current_base_init_list = nreverse (current_base_init_list);
for (; fields; fields = TREE_CHAIN (fields))
{
tree comp, init, t;
- if (TREE_CODE (fields) != FIELD_DECL)
+ tree field = fields;
+
+ if (TREE_CODE (field) != FIELD_DECL)
continue;
- if (DECL_NAME (fields))
+ if (DECL_NAME (field))
{
- if (VFIELD_NAME_P (DECL_NAME (fields)))
+ if (VFIELD_NAME_P (DECL_NAME (field)))
continue;
- if (VBASE_NAME_P (DECL_NAME (fields)))
+ if (VBASE_NAME_P (DECL_NAME (field)))
continue;
/* True for duplicate members. */
- if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
+ if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
continue;
}
- else if ((t = TREE_TYPE (fields)) != NULL_TREE
+ else if ((t = TREE_TYPE (field)) != NULL_TREE
&& TREE_CODE (t) == UNION_TYPE
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
&& TYPE_FIELDS (t) != NULL_TREE)
- fields = largest_union_member (t);
+ field = largest_union_member (t);
else
continue;
- comp = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields);
- init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields);
+ comp = build (COMPONENT_REF, TREE_TYPE (field), C_C_D, field);
+ init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
}
all derivations; this is applied before the explicit action, if one
is given. Keep this in mind when reading the actions. */
-/* Also note: this version contains experimental exception
- handling features. They could break, change, disappear,
- or otherwise exhibit volatile behavior. Don't depend on
- me (Michael Tiemann) to protect you from any negative impact
- this may have on your professional, personal, or spiritual life.
-
- NEWS FLASH: This version now supports the exception handling
- syntax of Stroustrup's 2nd edition, if -fansi-exceptions is given.
- THIS IS WORK IN PROGRESS!!! The type of the 'throw' and the
- 'catch' much match EXACTLY (no inheritance support or coercions).
- Also, throw-specifications of functions don't work.
- Destructors aren't called correctly. Etc, etc. --Per Bothner.
- */
-
%{
/* Cause the `yydebug' variable to be defined. */
#define YYDEBUG 1
%type <ttype> object aggr
%type <itype> new delete
/* %type <ttype> primary_no_id */
-%type <ttype> nonmomentary_expr
+%type <ttype> nonmomentary_expr maybe_parmlist
%type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
%type <ttype> template_header template_parm_list template_parm
%type <ttype> template_type_parm
{ if (pending_lang_change) do_pending_lang_change(); }
extdef
{ if (! global_bindings_p () && ! pseudo_global_level_p())
- pop_everything (); }
+ pop_everything ();
+ prefix_attributes = NULL_TREE; }
;
extdef:
$$ = $2;
}
}
- | component_decl_list ';'
;
component_decl:
{ $$ = finish_method ($$); }
| fn.def2 '{' /* nodecls compstmt */
{ $$ = finish_method ($$); }
+ | ';'
+ { $$ = NULL_TREE; }
;
component_decl_1:
/* These rules must follow the rules for function declarations
and component declarations. That way, longer rules are preferred. */
+suspend_mom:
+ { $<itype>$ = suspend_momentary (); }
+
/* An expression which will not live on the momentary obstack. */
nonmomentary_expr:
- { $<itype>$ = suspend_momentary (); } expr
+ suspend_mom expr
{ resume_momentary ((int) $<itype>1); $$ = $2; }
;
+/* An expression which will not live on the momentary obstack. */
+maybe_parmlist:
+ suspend_mom '(' nonnull_exprlist ')'
+ { resume_momentary ((int) $<itype>1); $$ = $3; }
+ | suspend_mom '(' parmlist ')'
+ { resume_momentary ((int) $<itype>1); $$ = $3; }
+ | suspend_mom LEFT_RIGHT
+ { resume_momentary ((int) $<itype>1); $$ = empty_parms (); }
+ | suspend_mom '(' error ')'
+ { resume_momentary ((int) $<itype>1); $$ = NULL_TREE; }
+ ;
+
/* A declarator that is allowed only after an explicit typespec. */
/* may all be followed by prec '.' */
after_type_declarator:
;
direct_after_type_declarator:
- direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
- { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
- | direct_after_type_declarator '(' parmlist ')' type_quals %prec '.'
- { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
- | direct_after_type_declarator LEFT_RIGHT type_quals %prec '.'
- { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
- | direct_after_type_declarator '(' error ')' type_quals %prec '.'
- { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
+ direct_after_type_declarator maybe_parmlist type_quals %prec '.'
+ { $$ = build_parse_node (CALL_EXPR, $$, $2, $3); }
| direct_after_type_declarator '[' nonmomentary_expr ']'
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
| direct_after_type_declarator '[' ']'
;
complex_direct_notype_declarator:
- direct_notype_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
- { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
- | direct_notype_declarator '(' parmlist ')' type_quals %prec '.'
- { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
- | direct_notype_declarator LEFT_RIGHT type_quals %prec '.'
- { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
- | direct_notype_declarator '(' error ')' type_quals %prec '.'
- { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
+ direct_notype_declarator maybe_parmlist type_quals %prec '.'
+ { $$ = build_parse_node (CALL_EXPR, $$, $2, $3); }
| '(' complex_notype_declarator ')'
{ $$ = $2; }
| direct_notype_declarator '[' nonmomentary_expr ']'
simple_stmt:
decl
- { finish_stmt (); }
+ { finish_stmt ();
+ prefix_attributes = NULL_TREE; }
| expr ';'
{
tree expr = $1;
| SWITCH .pushlevel '(' condition ')'
{ emit_line_note (input_filename, lineno);
c_expand_start_case ($4);
+ push_switch ();
/* Don't let the tree nodes for $4 be discarded by
clear_momentary during the parsing of the next stmt. */
push_momentary (); }
implicitly_scoped_stmt
{ expand_end_case ($4);
pop_momentary ();
+ pop_switch ();
expand_end_bindings (getdecls (), kept_level_p (), 1);
poplevel (kept_level_p (), 1, 0);
pop_momentary ();
DECL_INTERFACE_KNOWN (r) = 0;
DECL_INLINE (r) = DECL_INLINE (t);
DECL_THIS_INLINE (r) = DECL_THIS_INLINE (t);
+ TREE_READONLY (r) = TREE_READONLY (t);
+ TREE_THIS_VOLATILE (r) = TREE_THIS_VOLATILE (t);
{
#if 0 /* Maybe later. -jason */
struct tinst_level *til = tinst_for_decl();
If `interface', ext ref. */
if (CLASSTYPE_INTERFACE_KNOWN (context))
DECIDE (!CLASSTYPE_INTERFACE_ONLY (context));
-#if 0 /* This doesn't get us stuff needed only by the file initializer. */
+#if 1 /* This doesn't get us stuff needed only by the file initializer. */
DECIDE (TREE_USED (t));
#else /* This compiles too much stuff, but that's probably better in
most cases than never compiling the stuff we need. */
static tree get_delta_difference PROTO((tree, tree, int));
extern rtx original_result_rtx;
+extern int warn_synth;
/* Return the target type of TYPE, which meas return T for:
T*, T&, T[], T (...), and otherwise, just T. */
pedwarn ("ANSI C++ forbids calling `main' from within program");
}
+ if (pedantic && DECL_THIS_INLINE (function) && ! DECL_INITIAL (function)
+ && ! DECL_ARTIFICIAL (function)
+ && ! DECL_PENDING_INLINE_INFO (function))
+ cp_pedwarn ("inline function `%#D' called before definition",
+ function);
+
/* Differs from default_conversion by not setting TREE_ADDRESSABLE
(because calling an inline function does not mean the function
needs to be separately compiled). */
&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)
|| is_method))
{
- error ("called object is not a function");
+ cp_error ("`%E' cannot be used as a function", function);
return error_mark_node;
}
code2 = TREE_CODE (type2);
}
+ if (code1 == RECORD_TYPE && code2 == RECORD_TYPE
+ && real_lvalue_p (op1) && real_lvalue_p (op2)
+ && comptypes (type1, type2, -1))
+ {
+ type1 = build_reference_type (type1);
+ type2 = build_reference_type (type2);
+ result_type = common_type (type1, type2);
+ op1 = convert_to_reference (result_type, op1, CONV_IMPLICIT,
+ LOOKUP_NORMAL, NULL_TREE);
+ op2 = convert_to_reference (result_type, op2, CONV_IMPLICIT,
+ LOOKUP_NORMAL, NULL_TREE);
+ }
/* Quickly detect the usual case where op1 and op2 have the same type
after promotion. */
- if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
+ else if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
{
if (type1 == type2)
result_type = type1;
if (TREE_CONSTANT (ifexp))
return integer_zerop (ifexp) ? op2 : op1;
- return fold (build (COND_EXPR, result_type, ifexp, op1, op2));
+ return convert_from_reference
+ (fold (build (COND_EXPR, result_type, ifexp, op1, op2)));
}
\f
/* Handle overloading of the ',' operator when needed. Otherwise,
cp_error ("`%T' does not define operator=", lhstype);
else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (lhstype)
&& TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))
- /* Do the default thing */;
+ {
+ if (warn_synth)
+ /* If we care about this, do overload resolution. */
+ build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
+ lhs, rhs, make_node (NOP_EXPR));
+
+ /* Do the default thing */;
+ }
else
{
result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
tree tail1 = tail;
next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
TREE_VALUE (tail), &tail1);
+ if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))
+ && TYPE_MAIN_VARIANT (TREE_TYPE (type)) != TYPE_MAIN_VARIANT (TREE_TYPE (next1)))
+ {
+ /* The fact this needs to be done suggests this code needs
+ to be totally rewritten. */
+ next1 = convert_for_initialization (NULL_TREE, TREE_TYPE (type), next1, LOOKUP_NORMAL, "initialization", NULL_TREE, 0);
+ }
my_friendly_assert (tail1 == 0
|| TREE_CODE (tail1) == TREE_LIST, 319);
if (tail == tail1 && len < 0)
if (expr_as_ctor == error_mark_node)
return error_mark_node;
- if (current_function_decl)
- return build_cplus_new (type, expr_as_ctor, 1);
-
- {
- register tree parm = TREE_OPERAND (expr_as_ctor, 1);
-
- /* Initializers for static variables and parameters have
- to handle doing the initialization and cleanup themselves. */
- my_friendly_assert (TREE_CODE (expr_as_ctor) == CALL_EXPR, 322);
-#if 0
- /* The following assertion fails in cases where we are initializing
- a static member variable of a particular instance of a template
- class with a call to a constructor of the given instance, as in:
-
- TMPL<int> object = TMPL<int>();
-
- Curiously, the assertion does not fail if we do the same thing
- for a static member of a non-template class, as in:
-
- T object = T();
-
- I can't see why we should care here whether or not the initializer
- expression involves a call to `new', so for the time being, it
- seems best to just avoid doing this assertion. */
- my_friendly_assert (TREE_CALLS_NEW (TREE_VALUE (parm)), 323);
-#endif
- TREE_VALUE (parm) = NULL_TREE;
- expr_as_ctor = build_indirect_ref (expr_as_ctor, NULL_PTR);
- TREE_HAS_CONSTRUCTOR (expr_as_ctor) = 1;
- }
- return expr_as_ctor;
+ return build_cplus_new (type, expr_as_ctor, 1);
}
\f
/* Return the character string for the name that encodes the