summaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c131
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;
}