summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/semantics.c')
-rw-r--r--contrib/gcc/cp/semantics.c512
1 files changed, 250 insertions, 262 deletions
diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c
index a6f9afb..110eb3a 100644
--- a/contrib/gcc/cp/semantics.c
+++ b/contrib/gcc/cp/semantics.c
@@ -56,8 +56,6 @@ static void emit_associated_thunks PARAMS ((tree));
static void genrtl_try_block PARAMS ((tree));
static void genrtl_eh_spec_block PARAMS ((tree));
static void genrtl_handler PARAMS ((tree));
-static void genrtl_ctor_stmt PARAMS ((tree));
-static void genrtl_subobject PARAMS ((tree));
static void genrtl_named_return_value PARAMS ((void));
static void cp_expand_stmt PARAMS ((tree));
static void genrtl_start_function PARAMS ((tree));
@@ -81,7 +79,7 @@ static tree clear_decl_rtl PARAMS ((tree *, int *, void *));
(SUBSTMT) = (COND); \
} while (0)
-/* Returns non-zero if the current statement is a full expression,
+/* Returns nonzero if the current statement is a full expression,
i.e. temporaries created during that statement should be destroyed
at the end of the statement. */
@@ -99,7 +97,7 @@ stmt_tree
current_stmt_tree ()
{
return (cfun
- ? &cfun->language->x_stmt_tree
+ ? &cfun->language->base.x_stmt_tree
: &scope_chain->x_stmt_tree);
}
@@ -111,7 +109,7 @@ int
anon_aggr_type_p (node)
tree node;
{
- return (CLASS_TYPE_P (node) && TYPE_LANG_SPECIFIC(node)->anon_aggr);
+ return ANON_AGGR_TYPE_P (node);
}
/* Finish a scope. */
@@ -268,7 +266,6 @@ finish_then_clause (if_stmt)
tree if_stmt;
{
RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt));
- last_tree = if_stmt;
return if_stmt;
}
@@ -294,21 +291,8 @@ finish_else_clause (if_stmt)
void
finish_if_stmt ()
{
- do_poplevel ();
finish_stmt ();
-}
-
-void
-clear_out_block ()
-{
- /* If COND wasn't a declaration, clear out the
- block we made for it and start a new one here so the
- optimization in expand_end_loop will work. */
- if (getdecls () == NULL_TREE)
- {
- do_poplevel ();
- do_pushlevel ();
- }
+ do_poplevel ();
}
/* Begin a while-statement. Returns a newly created WHILE_STMT if
@@ -333,8 +317,29 @@ finish_while_stmt_cond (cond, while_stmt)
tree while_stmt;
{
cond = maybe_convert_cond (cond);
- FINISH_COND (cond, while_stmt, WHILE_COND (while_stmt));
- clear_out_block ();
+ if (processing_template_decl)
+ /* Don't mess with condition decls in a template. */
+ FINISH_COND (cond, while_stmt, WHILE_COND (while_stmt));
+ else if (getdecls () == NULL_TREE)
+ /* It was a simple condition; install it. */
+ WHILE_COND (while_stmt) = cond;
+ else
+ {
+ /* If there was a declaration in the condition, we can't leave it
+ there; transform
+ while (A x = 42) { }
+ to
+ while (true) { A x = 42; if (!x) break; } */
+ tree if_stmt;
+ WHILE_COND (while_stmt) = boolean_true_node;
+
+ if_stmt = begin_if_stmt ();
+ cond = build_unary_op (TRUTH_NOT_EXPR, cond, 0);
+ finish_if_stmt_cond (cond, if_stmt);
+ finish_break_stmt ();
+ finish_then_clause (if_stmt);
+ finish_if_stmt ();
+ }
}
/* Finish a while-statement, which may be given by WHILE_STMT. */
@@ -419,12 +424,12 @@ begin_for_stmt ()
r = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE);
NEW_FOR_SCOPE_P (r) = flag_new_for_scope > 0;
- add_stmt (r);
if (NEW_FOR_SCOPE_P (r))
{
do_pushlevel ();
note_level_for_for ();
}
+ add_stmt (r);
return r;
}
@@ -450,8 +455,29 @@ finish_for_cond (cond, for_stmt)
tree for_stmt;
{
cond = maybe_convert_cond (cond);
- FINISH_COND (cond, for_stmt, FOR_COND (for_stmt));
- clear_out_block ();
+ if (processing_template_decl)
+ /* Don't mess with condition decls in a template. */
+ FINISH_COND (cond, for_stmt, FOR_COND (for_stmt));
+ else if (getdecls () == NULL_TREE)
+ /* It was a simple condition; install it. */
+ FOR_COND (for_stmt) = cond;
+ else
+ {
+ /* If there was a declaration in the condition, we can't leave it
+ there; transform
+ for (; A x = 42;) { }
+ to
+ for (;;) { A x = 42; if (!x) break; } */
+ tree if_stmt;
+ FOR_COND (for_stmt) = NULL_TREE;
+
+ if_stmt = begin_if_stmt ();
+ cond = build_unary_op (TRUTH_NOT_EXPR, cond, 0);
+ finish_if_stmt_cond (cond, if_stmt);
+ finish_break_stmt ();
+ finish_then_clause (if_stmt);
+ finish_if_stmt ();
+ }
}
/* Finish the increment-EXPRESSION in a for-statement, which may be
@@ -504,9 +530,9 @@ tree
begin_switch_stmt ()
{
tree r;
+ do_pushlevel ();
r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
add_stmt (r);
- do_pushlevel ();
return r;
}
@@ -562,11 +588,11 @@ finish_switch_stmt (switch_stmt)
{
RECHAIN_STMTS (switch_stmt, SWITCH_BODY (switch_stmt));
pop_switch ();
- do_poplevel ();
finish_stmt ();
+ do_poplevel ();
}
-/* Generate the RTL for T, which is a TRY_BLOCK. */
+/* Generate the RTL for T, which is a TRY_BLOCK. */
static void
genrtl_try_block (t)
@@ -603,7 +629,7 @@ genrtl_try_block (t)
}
}
-/* Generate the RTL for T, which is an EH_SPEC_BLOCK. */
+/* Generate the RTL for T, which is an EH_SPEC_BLOCK. */
static void
genrtl_eh_spec_block (t)
@@ -712,7 +738,7 @@ finish_function_handler_sequence (try_block)
check_handlers (TRY_HANDLERS (try_block));
}
-/* Generate the RTL for T, which is a HANDLER. */
+/* Generate the RTL for T, which is a HANDLER. */
static void
genrtl_handler (t)
@@ -781,22 +807,7 @@ finish_handler (handler)
RECHAIN_STMTS (handler, HANDLER_BODY (handler));
}
-/* Generate the RTL for T, which is a CTOR_STMT. */
-
-static void
-genrtl_ctor_stmt (t)
- tree t;
-{
- if (CTOR_BEGIN_P (t))
- begin_protect_partials ();
- else
- /* After this point, any exceptions will cause the
- destructor to be executed, so we no longer need to worry
- about destroying the various subobjects ourselves. */
- end_protect_partials ();
-}
-
-/* Begin a compound-statement. If HAS_NO_SCOPE is non-zero, the
+/* Begin a compound-statement. If HAS_NO_SCOPE is nonzero, the
compound-statement does not define a scope. Returns a new
COMPOUND_STMT if appropriate. */
@@ -835,7 +846,7 @@ begin_compound_stmt (has_no_scope)
}
/* Finish a compound-statement, which may be given by COMPOUND_STMT.
- If HAS_NO_SCOPE is non-zero, the compound statement does not define
+ If HAS_NO_SCOPE is nonzero, the compound statement does not define
a scope. */
tree
@@ -880,9 +891,6 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
tree r;
tree t;
- if (TREE_CHAIN (string))
- string = combine_strings (string);
-
if (cv_qualifier != NULL_TREE
&& cv_qualifier != ridpointers[(int) RID_VOLATILE])
{
@@ -927,7 +935,7 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
tree operand;
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
- operand = TREE_VALUE (output_operands);
+ operand = TREE_VALUE (t);
if (!parse_output_constraint (&constraint,
i, ninputs, noutputs,
@@ -948,7 +956,7 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
DECL_RTL for the OPERAND -- which we don't have at this
point. */
if (!allows_reg && DECL_P (operand))
- mark_addressable (operand);
+ cxx_mark_addressable (operand);
}
}
@@ -980,38 +988,28 @@ finish_label_decl (name)
add_decl_stmt (decl);
}
-/* Generate the RTL for a SUBOBJECT. */
-
-static void
-genrtl_subobject (cleanup)
- tree cleanup;
-{
- add_partial_entry (cleanup);
-}
-
-/* We're in a constructor, and have just constructed a a subobject of
- *THIS. CLEANUP is code to run if an exception is thrown before the
- end of the current function is reached. */
+/* When DECL goes out of scope, make sure that CLEANUP is executed. */
void
-finish_subobject (cleanup)
+finish_decl_cleanup (decl, cleanup)
+ tree decl;
tree cleanup;
{
- tree r = build_stmt (SUBOBJECT, cleanup);
- add_stmt (r);
+ add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup));
}
-/* When DECL goes out of scope, make sure that CLEANUP is executed. */
+/* If the current scope exits with an exception, run CLEANUP. */
-void
-finish_decl_cleanup (decl, cleanup)
- tree decl;
+void
+finish_eh_cleanup (cleanup)
tree cleanup;
{
- add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup));
+ tree r = build_stmt (CLEANUP_STMT, NULL_TREE, cleanup);
+ CLEANUP_EH_ONLY (r) = 1;
+ add_stmt (r);
}
-/* Generate the RTL for a RETURN_INIT. */
+/* Generate the RTL for a RETURN_INIT. */
static void
genrtl_named_return_value ()
@@ -1031,7 +1029,7 @@ genrtl_named_return_value ()
the return value. */
SET_DECL_RTL (decl, gen_reg_rtx (GET_MODE (DECL_RTL (decl))));
if (TREE_ADDRESSABLE (decl))
- put_var_into_stack (decl);
+ put_var_into_stack (decl, /*rescan=*/true);
}
emit_local_var (decl);
@@ -1093,67 +1091,30 @@ finish_named_return_value (return_id, init)
DECL_UNINLINABLE (current_function_decl) = 1;
}
-/* The INIT_LIST is a list of mem-initializers, in the order they were
- written by the user. The TREE_VALUE of each node is a list of
- initializers for a particular subobject. The TREE_PURPOSE is a
- FIELD_DECL is the initializer is for a non-static data member, and
- a class type if the initializer is for a base class. */
+/* Begin processing a mem-initializer-list. */
void
-finish_mem_initializers (init_list)
- tree init_list;
+begin_mem_initializers ()
{
- tree member_init_list;
- tree base_init_list;
- tree last_base_warned_about;
- tree next;
- tree init;
+ if (! DECL_CONSTRUCTOR_P (current_function_decl))
+ error ("only constructors take base initializers");
+}
- member_init_list = NULL_TREE;
- base_init_list = NULL_TREE;
- last_base_warned_about = NULL_TREE;
+/* The MEM_INITS is a list of mem-initializers, in reverse of the
+ order they were written by the user. Each node is as for
+ emit_mem_initializers. */
- for (init = init_list; init; init = next)
- {
- next = TREE_CHAIN (init);
- if (TREE_CODE (TREE_PURPOSE (init)) == FIELD_DECL)
- {
- TREE_CHAIN (init) = member_init_list;
- member_init_list = init;
-
- /* We're running through the initializers from right to left
- as we process them here. So, if we see a data member
- initializer after we see a base initializer, that
- actually means that the base initializer preceded the
- data member initializer. */
- if (warn_reorder && last_base_warned_about != base_init_list)
- {
- tree base;
-
- for (base = base_init_list;
- base != last_base_warned_about;
- base = TREE_CHAIN (base))
- {
- warning ("base initializer for `%T'",
- TREE_PURPOSE (base));
- warning (" will be re-ordered to precede member initializations");
- }
-
- last_base_warned_about = base_init_list;
- }
- }
- else
- {
- TREE_CHAIN (init) = base_init_list;
- base_init_list = init;
- }
- }
+void
+finish_mem_initializers (tree mem_inits)
+{
+ /* Reorder the MEM_INITS so that they are in the order they appeared
+ in the source program. */
+ mem_inits = nreverse (mem_inits);
if (processing_template_decl)
- add_stmt (build_min_nt (CTOR_INITIALIZER,
- member_init_list, base_init_list));
+ add_stmt (build_min_nt (CTOR_INITIALIZER, mem_inits));
else
- emit_base_init (member_init_list, base_init_list);
+ emit_mem_initializers (mem_inits);
}
/* Returns the stack of SCOPE_STMTs for the current function. */
@@ -1161,7 +1122,7 @@ finish_mem_initializers (init_list)
tree *
current_scope_stmt_stack ()
{
- return &cfun->language->x_scope_stmt_stack;
+ return &cfun->language->base.x_scope_stmt_stack;
}
/* Finish a parenthesized expression EXPR. */
@@ -1171,7 +1132,7 @@ finish_parenthesized_expr (expr)
tree expr;
{
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expr))))
- /* This inhibits warnings in truthvalue_conversion. */
+ /* This inhibits warnings in c_common_truthvalue_conversion. */
C_SET_EXP_ORIGINAL_CODE (expr, ERROR_MARK);
if (TREE_CODE (expr) == OFFSET_REF)
@@ -1263,32 +1224,87 @@ finish_stmt_expr (rtl_expr)
return result;
}
-/* Finish a call to FN with ARGS. Returns a representation of the
- call. */
+/* Generate an expression for `FN (ARGS)'.
+
+ If DISALLOW_VIRTUAL is true, the call to FN will be not generated
+ as a virtual call, even if FN is virtual. (This flag is set when
+ encountering an expression where the function name is explicitly
+ qualified. For example a call to `X::f' never generates a virtual
+ call.)
+
+ Returns code for the call. */
tree
-finish_call_expr (fn, args, koenig)
- tree fn;
- tree args;
- int koenig;
+finish_call_expr (tree fn, tree args, bool disallow_virtual)
{
- tree result;
+ if (fn == error_mark_node || args == error_mark_node)
+ return error_mark_node;
+
+ if (processing_template_decl)
+ return build_nt (CALL_EXPR, fn, args, NULL_TREE);
- if (koenig)
+ /* ARGS should be a list of arguments. */
+ my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
+ 20020712);
+
+ if (BASELINK_P (fn))
{
- if (TREE_CODE (fn) == BIT_NOT_EXPR)
- fn = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND (fn, 0));
- else if (TREE_CODE (fn) != TEMPLATE_ID_EXPR)
- fn = do_identifier (fn, 2, args);
- }
- result = build_x_function_call (fn, args, current_class_ref);
+ tree object;
+
+ /* A call to a member function. From [over.call.func]:
+
+ If the keyword this is in scope and refers to the class of
+ that member function, or a derived class thereof, then the
+ function call is transformed into a qualified function call
+ using (*this) as the postfix-expression to the left of the
+ . operator.... [Otherwise] a contrived object of type T
+ becomes the implied object argument.
+
+ This paragraph is unclear about this situation:
+
+ struct A { void f(); };
+ struct B : public A {};
+ struct C : public A { void g() { B::f(); }};
+
+ In particular, for `B::f', this paragraph does not make clear
+ whether "the class of that member function" refers to `A' or
+ to `B'. We believe it refers to `B'. */
+ if (current_class_type
+ && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
+ current_class_type)
+ && current_class_ref)
+ object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
+ NULL);
+ else
+ {
+ tree representative_fn;
- if (TREE_CODE (result) == CALL_EXPR
- && (! TREE_TYPE (result)
- || TREE_CODE (TREE_TYPE (result)) != VOID_TYPE))
- result = require_complete_type (result);
+ representative_fn = BASELINK_FUNCTIONS (fn);
+ if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR)
+ representative_fn = TREE_OPERAND (representative_fn, 0);
+ representative_fn = get_first_fn (representative_fn);
+ object = build_dummy_object (DECL_CONTEXT (representative_fn));
+ }
- return result;
+ return build_new_method_call (object, fn, args, NULL_TREE,
+ (disallow_virtual
+ ? LOOKUP_NONVIRTUAL : 0));
+ }
+ else if (is_overloaded_fn (fn))
+ /* A call to a namespace-scope function. */
+ return build_new_function_call (fn, args);
+ else if (CLASS_TYPE_P (TREE_TYPE (fn)))
+ {
+ /* If the "function" is really an object of class type, it might
+ have an overloaded `operator ()'. */
+ tree result;
+ result = build_opfncall (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE);
+ if (result)
+ return result;
+ }
+
+ /* A call where the function is unknown. */
+ return build_function_call (fn, args);
}
/* Finish a call to a postfix increment or decrement or EXPR. (Which
@@ -1348,14 +1364,6 @@ finish_object_call_expr (fn, object, args)
tree object;
tree args;
{
-#if 0
- /* This is a future direction of this code, but because
- build_x_function_call cannot always undo what is done in
- build_component_ref entirely yet, we cannot do this. */
-
- tree real_fn = build_component_ref (object, fn, NULL_TREE, 1);
- return finish_call_expr (real_fn, args);
-#else
if (DECL_DECLARES_TYPE_P (fn))
{
if (processing_template_decl)
@@ -1374,9 +1382,11 @@ finish_object_call_expr (fn, object, args)
return error_mark_node;
}
}
-
- return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
-#endif
+
+ if (processing_template_decl || name_p (fn))
+ return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
+ else
+ return build_new_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
}
/* Finish a qualified member function call using OBJECT and ARGS as
@@ -1417,22 +1427,6 @@ finish_pseudo_destructor_call_expr (object, scope, destructor)
return cp_convert (void_type_node, object);
}
-/* Finish a call to a globally qualified member function FN using
- ARGS. Returns an expression for the call. */
-
-tree
-finish_qualified_call_expr (fn, args)
- tree fn;
- tree args;
-{
- if (processing_template_decl)
- return build_min_nt (CALL_EXPR, fn, args, NULL_TREE);
- else
- return build_member_call (TREE_OPERAND (fn, 0),
- TREE_OPERAND (fn, 1),
- args);
-}
-
/* Finish an expression of the form CODE EXPR. */
tree
@@ -1467,6 +1461,20 @@ finish_id_expr (expr)
return expr;
}
+/* Return the declaration for the function-name variable indicated by
+ ID. */
+
+tree
+finish_fname (tree id)
+{
+ tree decl;
+
+ decl = fname_decl (C_RID_CODE (id), id);
+ if (processing_template_decl)
+ decl = build_min_nt (LOOKUP_EXPR, DECL_NAME (decl));
+ return decl;
+}
+
static tree current_type_lookups;
/* Perform deferred access control for types used in the type of a
@@ -1524,20 +1532,17 @@ reset_type_access_control ()
current_type_lookups = NULL_TREE;
}
-/* Begin a function definition declared with DECL_SPECS and
- DECLARATOR. Returns non-zero if the function-declaration is
- legal. */
+/* Begin a function definition declared with DECL_SPECS, ATTRIBUTES,
+ and DECLARATOR. Returns nonzero if the function-declaration is
+ valid. */
int
-begin_function_definition (decl_specs, declarator)
+begin_function_definition (decl_specs, attributes, declarator)
tree decl_specs;
+ tree attributes;
tree declarator;
{
- tree specs;
- tree attrs;
-
- split_specs_attrs (decl_specs, &specs, &attrs);
- if (!start_function (specs, declarator, attrs, SF_DEFAULT))
+ if (!start_function (decl_specs, declarator, attributes, SF_DEFAULT))
return 0;
deferred_type_access_control ();
@@ -1589,7 +1594,7 @@ finish_translation_unit ()
while (current_namespace != global_namespace)
pop_namespace ();
- /* Do file scope __FUNCTION__ et al. */
+ /* Do file scope __FUNCTION__ et al. */
finish_fname_decls ();
finish_file ();
@@ -1632,8 +1637,27 @@ finish_template_template_parm (aggr, identifier)
return finish_template_type_parm (aggr, tmpl);
}
+/* ARGUMENT is the default-argument value for a template template
+ parameter. If ARGUMENT is invalid, issue error messages and return
+ the ERROR_MARK_NODE. Otherwise, ARGUMENT itself is returned. */
+
+tree
+check_template_template_default_arg (tree argument)
+{
+ if (TREE_CODE (argument) != TEMPLATE_DECL
+ && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM
+ && TREE_CODE (argument) != TYPE_DECL
+ && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
+ {
+ error ("invalid default template argument");
+ return error_mark_node;
+ }
+
+ return argument;
+}
+
/* Finish a parameter list, indicated by PARMS. If ELLIPSIS is
- non-zero, the parameter list was terminated by a `...'. */
+ nonzero, the parameter list was terminated by a `...'. */
tree
finish_parmlist (parms, ellipsis)
@@ -1661,7 +1685,7 @@ begin_class_definition (t)
if (t == error_mark_node)
return error_mark_node;
- /* Check the bases are accessible. */
+ /* Check the bases are accessible. */
decl_type_access_control (TYPE_NAME (t));
reset_type_access_control ();
@@ -1731,7 +1755,8 @@ begin_class_definition (t)
TYPE_BINFO_BASETYPES (t) = NULL_TREE;
TYPE_FIELDS (t) = NULL_TREE;
TYPE_METHODS (t) = NULL_TREE;
- CLASSTYPE_TAGS (t) = NULL_TREE;
+ CLASSTYPE_DECL_LIST (t) = NULL_TREE;
+ CLASSTYPE_NESTED_UDTS (t) = NULL;
CLASSTYPE_VBASECLASSES (t) = NULL_TREE;
TYPE_SIZE (t) = NULL_TREE;
}
@@ -1824,8 +1849,12 @@ finish_member_declaration (decl)
TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
TYPE_METHODS (current_class_type) = decl;
+
+ maybe_add_class_template_decl_list (current_class_type, decl,
+ /*friend_p=*/0);
}
- else
+ /* Enter the DECL into the scope of the class. */
+ else if (TREE_CODE (decl) == USING_DECL || pushdecl_class_level (decl))
{
/* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
go at the beginning. The reason is that lookup_field_1
@@ -1836,7 +1865,7 @@ finish_member_declaration (decl)
struct S { enum E { }; int E } s;
s.E = 3;
- is legal. In addition, the FIELD_DECLs must be maintained in
+ is valid. In addition, the FIELD_DECLs must be maintained in
declaration order so that class layout works as expected.
However, we don't need that order until class layout, so we
save a little time by putting FIELD_DECLs on in reverse order
@@ -1853,9 +1882,8 @@ finish_member_declaration (decl)
TYPE_FIELDS (current_class_type) = decl;
}
- /* Enter the DECL into the scope of the class. */
- if (TREE_CODE (decl) != USING_DECL)
- pushdecl_class_level (decl);
+ maybe_add_class_template_decl_list (current_class_type, decl,
+ /*friend_p=*/0);
}
}
@@ -1912,16 +1940,6 @@ begin_inline_definitions ()
do_pending_inlines ();
}
-/* Finish processing the inline function definitions cached during the
- processing of a class definition. */
-
-void
-finish_inline_definitions ()
-{
- if (current_class_type == NULL_TREE)
- clear_inline_text_obstack ();
-}
-
/* Finish processing the declaration of a member class template
TYPES whose template parameters are given by PARMS. */
@@ -1969,7 +1987,7 @@ finish_template_decl (parms)
/* Finish processing a template-id (which names a type) of the form
NAME < ARGS >. Return the TYPE_DECL for the type named by the
- template-id. If ENTERING_SCOPE is non-zero we are about to enter
+ template-id. If ENTERING_SCOPE is nonzero we are about to enter
the scope of template-id indicated. */
tree
@@ -2030,7 +2048,12 @@ finish_base_specifier (access_specifier, base_class)
{
tree result;
- if (! is_aggr_type (base_class, 1))
+ if (base_class == error_mark_node)
+ {
+ error ("invalid base-class specification");
+ result = NULL_TREE;
+ }
+ else if (! is_aggr_type (base_class, 1))
result = NULL_TREE;
else
{
@@ -2058,11 +2081,9 @@ check_multiple_declarators ()
contain at most one declarator.
We don't just use PROCESSING_TEMPLATE_DECL for the first
- condition since that would disallow the perfectly legal code,
+ condition since that would disallow the perfectly valid code,
like `template <class T> struct S { int i, j; };'. */
- tree scope = current_scope ();
-
- if (scope && TREE_CODE (scope) == FUNCTION_DECL)
+ if (at_function_scope_p ())
/* It's OK to write `template <class T> void f() { int i, j;}'. */
return;
@@ -2112,7 +2133,7 @@ finish_sizeof (t)
if (processing_template_decl)
return build_min_nt (SIZEOF_EXPR, t);
- return TYPE_P (t) ? c_sizeof (t) : expr_sizeof (t);
+ return TYPE_P (t) ? cxx_sizeof (t) : expr_sizeof (t);
}
/* Implement the __alignof keyword: Return the minimum required
@@ -2125,7 +2146,7 @@ finish_alignof (t)
if (processing_template_decl)
return build_min_nt (ALIGNOF_EXPR, t);
- return TYPE_P (t) ? c_alignof (complete_type (t)) : c_alignof_expr (t);
+ return TYPE_P (t) ? cxx_alignof (t) : c_alignof_expr (t);
}
/* Generate RTL for the statement T, and its substatements, and any
@@ -2137,10 +2158,6 @@ cp_expand_stmt (t)
{
switch (TREE_CODE (t))
{
- case CTOR_STMT:
- genrtl_ctor_stmt (t);
- break;
-
case TRY_BLOCK:
genrtl_try_block (t);
break;
@@ -2153,10 +2170,6 @@ cp_expand_stmt (t)
genrtl_handler (t);
break;
- case SUBOBJECT:
- genrtl_subobject (SUBOBJECT_CLEANUP (t));
- break;
-
case RETURN_INIT:
genrtl_named_return_value ();
break;
@@ -2211,7 +2224,7 @@ simplify_aggr_init_exprs_r (tp, walk_subtrees, data)
{
/* Replace the first argument with the address of the third
argument to the AGGR_INIT_EXPR. */
- mark_addressable (slot);
+ cxx_mark_addressable (slot);
args = tree_cons (NULL_TREE,
build1 (ADDR_EXPR,
build_pointer_type (TREE_TYPE (slot)),
@@ -2271,35 +2284,9 @@ emit_associated_thunks (fn)
enabling you to output all the thunks with the function itself. */
if (DECL_VIRTUAL_P (fn))
{
- tree binfo;
- tree v;
-
- for (binfo = TYPE_BINFO (DECL_CONTEXT (fn));
- binfo;
- binfo = TREE_CHAIN (binfo))
- for (v = BINFO_VIRTUALS (binfo); v; v = TREE_CHAIN (v))
- if (BV_FN (v) == fn
- && (!integer_zerop (BV_DELTA (v))
- || BV_USE_VCALL_INDEX_P (v)))
- {
- tree thunk;
- tree vcall_index;
-
- if (BV_USE_VCALL_INDEX_P (v))
- {
- vcall_index = BV_VCALL_INDEX (v);
- my_friendly_assert (vcall_index != NULL_TREE, 20000621);
- }
- else
- vcall_index = NULL_TREE;
-
- thunk = make_thunk (build1 (ADDR_EXPR,
- vfunc_ptr_type_node,
- fn),
- BV_DELTA (v),
- vcall_index);
- use_thunk (thunk, /*emit_p=*/1);
- }
+ tree thunk;
+ for (thunk = DECL_THUNKS (fn); thunk; thunk = TREE_CHAIN (thunk))
+ use_thunk (thunk, /*emit_p=*/1);
}
}
@@ -2311,6 +2298,7 @@ expand_body (fn)
{
int saved_lineno;
const char *saved_input_filename;
+ tree saved_function;
/* When the parser calls us after finishing the body of a template
function, we don't really want to expand the body. When we're
@@ -2388,21 +2376,23 @@ expand_body (fn)
if (DECL_EXTERNAL (fn))
return;
- timevar_push (TV_INTEGRATION);
-
- /* Optimize the body of the function before expanding it. */
- optimize_function (fn);
-
- timevar_pop (TV_INTEGRATION);
- timevar_push (TV_EXPAND);
-
/* Save the current file name and line number. When we expand the
body of the function, we'll set LINENO and INPUT_FILENAME so that
error-mesages come out in the right places. */
saved_lineno = lineno;
saved_input_filename = input_filename;
+ saved_function = current_function_decl;
lineno = DECL_SOURCE_LINE (fn);
input_filename = DECL_SOURCE_FILE (fn);
+ current_function_decl = fn;
+
+ timevar_push (TV_INTEGRATION);
+
+ /* Optimize the body of the function before expanding it. */
+ optimize_function (fn);
+
+ timevar_pop (TV_INTEGRATION);
+ timevar_push (TV_EXPAND);
genrtl_start_function (fn);
current_function_is_thunk = DECL_THUNK_P (fn);
@@ -2435,6 +2425,7 @@ expand_body (fn)
DECL_SAVED_TREE (fn) = NULL_TREE;
/* And restore the current source position. */
+ current_function_decl = saved_function;
lineno = saved_lineno;
input_filename = saved_input_filename;
extract_interface_info ();
@@ -2462,7 +2453,7 @@ nullify_returns_r (tp, walk_subtrees, data)
if (TYPE_P (*tp))
*walk_subtrees = 0;
else if (TREE_CODE (*tp) == RETURN_STMT)
- RETURN_EXPR (*tp) = NULL_TREE;
+ RETURN_STMT_EXPR (*tp) = NULL_TREE;
else if (TREE_CODE (*tp) == CLEANUP_STMT
&& CLEANUP_DECL (*tp) == nrv)
CLEANUP_EH_ONLY (*tp) = 1;
@@ -2516,10 +2507,7 @@ genrtl_start_function (fn)
function; we need the named return value info for
cp_copy_res_decl_for_inlining. */
if (! DECL_INLINE (fn))
- {
- free (DECL_SAVED_FUNCTION_DATA (fn));
- DECL_SAVED_FUNCTION_DATA (fn) = NULL;
- }
+ DECL_SAVED_FUNCTION_DATA (fn) = NULL;
}
/* Keep track of how many functions we're presently expanding. */
OpenPOWER on IntegriCloud