diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 131 |
1 files changed, 47 insertions, 84 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index cf0429e3f18..de0cf25d640 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -71,7 +71,7 @@ static void require_complete_types_for_parms (tree); static int ambi_op_p (enum tree_code); static int unary_op_p (enum tree_code); static void push_local_name (tree); -static tree grok_reference_init (tree, tree, tree, tree *, int); +static tree grok_reference_init (tree, tree, tree, int); static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *, int, int, tree); static int check_static_variable_definition (tree, tree); @@ -91,7 +91,7 @@ static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool); static int walk_namespaces_r (tree, walk_namespaces_fn, void *); static void maybe_deduce_size_from_array_init (tree, tree); static void layout_var_decl (tree); -static tree check_initializer (tree, tree, int, tree *); +static tree check_initializer (tree, tree, int, VEC(tree,gc) **); static void make_rtl_for_nonlocal_decl (tree, tree, const char *); static void save_function_data (tree); static void copy_type_enum (tree , tree); @@ -3270,7 +3270,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, return error_mark_node; } - if (want_template && !DECL_CLASS_TEMPLATE_P (t)) + if (want_template && !DECL_TYPE_TEMPLATE_P (t)) { if (complain & tf_error) error ("%<typename %T::%D%> names %q#T, which is not a class template", @@ -3338,7 +3338,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list, if (tmpl && TREE_CODE (tmpl) == TYPE_DECL) tmpl = maybe_get_template_decl_from_type_decl (tmpl); - if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) + if (!tmpl || !DECL_TYPE_TEMPLATE_P (tmpl)) { if (complain & tf_error) error ("no class template named %q#T in %q#T", name, context); @@ -4613,11 +4613,8 @@ start_decl_1 (tree decl, bool initialized) Quotes on semantics can be found in ARM 8.4.3. */ static tree -grok_reference_init (tree decl, tree type, tree init, tree *cleanup, - int flags) +grok_reference_init (tree decl, tree type, tree init, int flags) { - tree tmp; - if (init == NULL_TREE) { if ((DECL_LANG_SPECIFIC (decl) == 0 @@ -4643,62 +4640,8 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup, DECL_INITIAL for local references (instead assigning to them explicitly); we need to allow the temporary to be initialized first. */ - tmp = initialize_reference (type, init, decl, cleanup, flags, - tf_warning_or_error); - if (DECL_DECLARED_CONSTEXPR_P (decl)) - { - tmp = cxx_constant_value (tmp); - DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) - = reduced_constant_expression_p (tmp); - } - - if (tmp == error_mark_node) - return NULL_TREE; - else if (tmp == NULL_TREE) - { - error ("cannot initialize %qT from %qT", type, TREE_TYPE (init)); - return NULL_TREE; - } - - if (TREE_STATIC (decl) && !TREE_CONSTANT (tmp)) - return tmp; - - DECL_INITIAL (decl) = tmp; - - return NULL_TREE; -} - -/* Subroutine of check_initializer. We're initializing a DECL of - std::initializer_list<T> TYPE from a braced-init-list INIT, and need to - extend the lifetime of the underlying array to match that of the decl, - just like for reference initialization. CLEANUP is as for - grok_reference_init. */ - -static tree -build_init_list_var_init (tree decl, tree type, tree init, tree *array_init, - tree *cleanup) -{ - tree aggr_init, array, arrtype; - init = perform_implicit_conversion (type, init, tf_warning_or_error); - if (error_operand_p (init)) - return error_mark_node; - - aggr_init = TARGET_EXPR_INITIAL (init); - array = CONSTRUCTOR_ELT (aggr_init, 0)->value; - arrtype = TREE_TYPE (array); - STRIP_NOPS (array); - gcc_assert (TREE_CODE (array) == ADDR_EXPR); - array = TREE_OPERAND (array, 0); - /* If the array is constant, finish_compound_literal already made it a - static variable and we don't need to do anything here. */ - if (decl && TREE_CODE (array) == TARGET_EXPR) - { - tree var = set_up_extended_ref_temp (decl, array, cleanup, array_init); - var = build_address (var); - var = convert (arrtype, var); - CONSTRUCTOR_ELT (aggr_init, 0)->value = var; - } - return init; + return initialize_reference (type, init, flags, + tf_warning_or_error); } /* Designated initializers in arrays are not supported in GNU C++. @@ -5442,7 +5385,7 @@ build_aggr_init_full_exprs (tree decl, tree init, int flags) evaluated dynamically to initialize DECL. */ static tree -check_initializer (tree decl, tree init, int flags, tree *cleanup) +check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups) { tree type = TREE_TYPE (decl); tree init_code = NULL; @@ -5511,19 +5454,26 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) } else if (!init && DECL_REALLY_EXTERN (decl)) ; - else if (TREE_CODE (type) == REFERENCE_TYPE) - init = grok_reference_init (decl, type, init, cleanup, flags); - else if (init || type_build_ctor_call (type)) + else if (init || type_build_ctor_call (type) + || TREE_CODE (type) == REFERENCE_TYPE) { - if (!init) + if (TREE_CODE (type) == REFERENCE_TYPE) + { + init = grok_reference_init (decl, type, init, flags); + flags |= LOOKUP_ALREADY_DIGESTED; + } + else if (!init) check_for_uninitialized_const_var (decl); /* Do not reshape constructors of vectors (they don't need to be reshaped. */ else if (BRACE_ENCLOSED_INITIALIZER_P (init)) { if (is_std_init_list (type)) - init = build_init_list_var_init (decl, type, init, - &extra_init, cleanup); + { + init = perform_implicit_conversion (type, init, + tf_warning_or_error); + flags |= LOOKUP_ALREADY_DIGESTED; + } else if (TYPE_NON_AGGREGATE_CLASS (type)) { /* Don't reshape if the class has constructors. */ @@ -5540,7 +5490,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) else { init = reshape_init (type, init, tf_warning_or_error); - if (cxx_dialect >= cxx0x && SCALAR_TYPE_P (type)) + if (SCALAR_TYPE_P (type)) check_narrowing (type, init); } } @@ -5552,9 +5502,10 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) if (type == error_mark_node) return NULL_TREE; - if (type_build_ctor_call (type) - || (CLASS_TYPE_P (type) - && !(init && BRACE_ENCLOSED_INITIALIZER_P (init)))) + if ((type_build_ctor_call (type) || CLASS_TYPE_P (type)) + && !(flags & LOOKUP_ALREADY_DIGESTED) + && !(init && BRACE_ENCLOSED_INITIALIZER_P (init) + && CP_AGGREGATE_TYPE_P (type))) { init_code = build_aggr_init_full_exprs (decl, init, flags); @@ -5596,7 +5547,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) if (init && TREE_CODE (init) != TREE_VEC) { - init_code = store_init_value (decl, init, flags); + init_code = store_init_value (decl, init, cleanups, flags); if (pedantic && TREE_CODE (type) == ARRAY_TYPE && DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST @@ -5958,7 +5909,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, tree asmspec_tree, int flags) { tree type; - tree cleanup; + VEC(tree,gc) *cleanups = NULL; const char *asmspec = NULL; int was_readonly = 0; bool var_definition_p = false; @@ -5981,9 +5932,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (type == error_mark_node) return; - /* Assume no cleanup is required. */ - cleanup = NULL_TREE; - /* If a name was specified, get the string. */ if (at_namespace_scope_p ()) asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); @@ -6103,9 +6051,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, /* This variable seems to be a non-dependent constant, so process its initializer. If check_initializer returns non-null the initialization wasn't constant after all. */ - tree init_code = check_initializer (decl, init, flags, &cleanup); + tree init_code; + cleanups = make_tree_vector (); + init_code = check_initializer (decl, init, flags, &cleanups); if (init_code == NULL_TREE) init = NULL_TREE; + release_tree_vector (cleanups); } else if (!DECL_PRETTY_FUNCTION_P (decl)) /* Deduce array size even if the initializer is dependent. */ @@ -6204,7 +6155,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, error ("Java object %qD not allocated with %<new%>", decl); init = NULL_TREE; } - init = check_initializer (decl, init, flags, &cleanup); + cleanups = make_tree_vector (); + init = check_initializer (decl, init, flags, &cleanups); /* Thread-local storage cannot be dynamically initialized. */ if (DECL_THREAD_LOCAL_P (decl) && init) { @@ -6369,8 +6321,13 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, /* If a CLEANUP_STMT was created to destroy a temporary bound to a reference, insert it in the statement-tree now. */ - if (cleanup) - push_cleanup (decl, cleanup, false); + if (cleanups) + { + unsigned i; tree t; + FOR_EACH_VEC_ELT (tree, cleanups, i, t) + push_cleanup (decl, t, false); + release_tree_vector (cleanups); + } if (was_readonly) TREE_READONLY (decl) = 1; @@ -9792,6 +9749,11 @@ grokdeclarator (const cp_declarator *declarator, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); + if (declspecs->specs[(int)ds_alias]) + /* Acknowledge that this was written: + `using analias = atype;'. */ + TYPE_DECL_ALIAS_P (decl) = 1; + return decl; } @@ -13066,6 +13028,7 @@ save_function_data (tree decl) f->base.x_stmt_tree.x_cur_stmt_list = NULL; f->bindings = NULL; f->x_local_names = NULL; + f->base.local_typedefs = NULL; } |