X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl.c;h=4ae924b32ad42e72276c5d94efc1de57c1fb88eb;hb=5f8e000d9979223bf654d46ba7d844468490f472;hp=c720f6c33a377b619bc5fb6c802cb34c403f080a;hpb=3bb63aebd8060e2baf8baf687c1a320e81ebba91;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c720f6c33a3..4ae924b32ad 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "cp-tree.h" #include "tree-inline.h" #include "decl.h" +#include "intl.h" #include "output.h" #include "except.h" #include "toplev.h" @@ -103,7 +104,6 @@ static tree build_cp_library_fn (tree, enum tree_code, tree); static void store_parm_decls (tree); static void initialize_local_var (tree, tree); static void expand_static_init (tree, tree); -static tree next_initializable_field (tree); /* The following symbols are subsumed in the cp_global_trees array, and listed here individually for documentation purposes. @@ -520,8 +520,6 @@ poplevel (int keep, int reverse, int functionbody) /* The chain of decls was accumulated in reverse order. Put it into forward order, just for cleanliness. */ tree decls; - int tmp = functionbody; - int real_functionbody; tree subblocks; tree block; tree decl; @@ -535,8 +533,8 @@ poplevel (int keep, int reverse, int functionbody) gcc_assert (current_binding_level->kind != sk_class); - real_functionbody = (current_binding_level->kind == sk_cleanup - ? ((functionbody = 0), tmp) : functionbody); + if (current_binding_level->kind == sk_cleanup) + functionbody = 0; subblocks = functionbody >= 0 ? current_binding_level->blocks : 0; gcc_assert (!VEC_length(cp_class_binding, @@ -849,6 +847,7 @@ create_implicit_typedef (tree name, tree type) amongst these. */ SET_DECL_IMPLICIT_TYPEDEF_P (decl); TYPE_NAME (type) = decl; + TYPE_STUB_DECL (type) = decl; return decl; } @@ -935,7 +934,7 @@ decls_match (tree newdecl, tree olddecl) #ifdef NO_IMPLICIT_EXTERN_C /* A new declaration doesn't match a built-in one unless it is also extern "C". */ - if (DECL_BUILT_IN (olddecl) + if (DECL_IS_BUILTIN (olddecl) && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl)) return 0; #endif @@ -1034,8 +1033,6 @@ decls_match (tree newdecl, tree olddecl) void warn_extern_redeclared_static (tree newdecl, tree olddecl) { - tree name; - if (TREE_CODE (newdecl) == TYPE_DECL || TREE_CODE (newdecl) == TEMPLATE_DECL || TREE_CODE (newdecl) == CONST_DECL @@ -1058,7 +1055,6 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl) && DECL_ARTIFICIAL (olddecl)) return; - name = DECL_ASSEMBLER_NAME (newdecl); permerror (input_location, "%qD was declared % and later %", newdecl); permerror (input_location, "previous declaration of %q+D", olddecl); } @@ -1183,9 +1179,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) bad choice of name. */ if (! TREE_PUBLIC (newdecl)) { - warning (OPT_Wshadow, "shadowing %s function %q#D", - DECL_BUILT_IN (olddecl) ? "built-in" : "library", - olddecl); + warning (OPT_Wshadow, + DECL_BUILT_IN (olddecl) + ? G_("shadowing built-in function %q#D") + : G_("shadowing library function %q#D"), olddecl); /* Discard the old built-in function. */ return NULL_TREE; } @@ -1256,9 +1253,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) olddecl); } else - warning (OPT_Wshadow, "shadowing %s function %q#D", - DECL_BUILT_IN (olddecl) ? "built-in" : "library", - olddecl); + warning (OPT_Wshadow, + DECL_BUILT_IN (olddecl) + ? G_("shadowing built-in function %q#D") + : G_("shadowing library function %q#D"), olddecl); } else /* Discard the old built-in function. */ @@ -2094,6 +2092,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) TREE_USED (newdecl) = 1; else if (TREE_USED (newdecl)) TREE_USED (olddecl) = 1; + if (DECL_PRESERVE_P (olddecl)) + DECL_PRESERVE_P (newdecl) = 1; + else if (DECL_PRESERVE_P (newdecl)) + DECL_PRESERVE_P (olddecl) = 1; if (TREE_CODE (newdecl) == FUNCTION_DECL) { @@ -2211,7 +2213,7 @@ redeclaration_error_message (tree newdecl, tree olddecl) if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl))) return NULL; else - return "redefinition of %q#D"; + return G_("redefinition of %q#D"); } else if (TREE_CODE (newdecl) == FUNCTION_DECL) { @@ -2227,7 +2229,7 @@ redeclaration_error_message (tree newdecl, tree olddecl) if (DECL_NAMESPACE_SCOPE_P (olddecl) && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl) && ! decls_match (olddecl, newdecl)) - return "%qD conflicts with used function"; + return G_("%qD conflicts with used function"); /* We'll complain about linkage mismatches in warn_extern_redeclared_static. */ @@ -2237,10 +2239,10 @@ redeclaration_error_message (tree newdecl, tree olddecl) && DECL_INITIAL (newdecl) != NULL_TREE) { if (DECL_NAME (olddecl) == NULL_TREE) - return "%q#D not declared in class"; + return G_("%q#D not declared in class"); else if (!GNU_INLINE_P (olddecl) || GNU_INLINE_P (newdecl)) - return "redefinition of %q#D"; + return G_("redefinition of %q#D"); } if (DECL_DECLARED_INLINE_P (olddecl) && DECL_DECLARED_INLINE_P (newdecl)) @@ -2251,9 +2253,11 @@ redeclaration_error_message (tree newdecl, tree olddecl) if (olda != newa) { if (newa) - return "%q+D redeclared inline with % attribute"; + return G_("%q+D redeclared inline with " + "% attribute"); else - return "%q+D redeclared inline without % attribute"; + return G_("%q+D redeclared inline without " + "% attribute"); } } @@ -2267,7 +2271,7 @@ redeclaration_error_message (tree newdecl, tree olddecl) { if (COMPLETE_TYPE_P (TREE_TYPE (newdecl)) && COMPLETE_TYPE_P (TREE_TYPE (olddecl))) - return "redefinition of %q#D"; + return G_("redefinition of %q#D"); return NULL; } @@ -2284,7 +2288,7 @@ redeclaration_error_message (tree newdecl, tree olddecl) ot = DECL_TEMPLATE_RESULT (template_for_substitution (ot)); if (DECL_INITIAL (nt) && DECL_INITIAL (ot) && (!GNU_INLINE_P (ot) || GNU_INLINE_P (nt))) - return "redefinition of %q#D"; + return G_("redefinition of %q#D"); if (DECL_DECLARED_INLINE_P (ot) && DECL_DECLARED_INLINE_P (nt)) { @@ -2294,9 +2298,11 @@ redeclaration_error_message (tree newdecl, tree olddecl) if (olda != newa) { if (newa) - return "%q+D redeclared inline with % attribute"; + return G_("%q+D redeclared inline with " + "% attribute"); else - return "%q+D redeclared inline without % attribute"; + return G_("%q+D redeclared inline without " + "% attribute"); } } @@ -2311,7 +2317,8 @@ redeclaration_error_message (tree newdecl, tree olddecl) && !check_default_tmpl_args (nt, DECL_TEMPLATE_PARMS (newdecl), /*is_primary=*/1, /*is_partial=*/0, /*is_friend_decl=*/2)) - return "redeclaration of friend %q#D may not have default template arguments"; + return G_("redeclaration of friend %q#D " + "may not have default template arguments"); return NULL; } @@ -2324,11 +2331,11 @@ redeclaration_error_message (tree newdecl, tree olddecl) /* Only variables can be thread-local, and all declarations must agree on this property. */ if (DECL_THREAD_LOCAL_P (newdecl)) - return "thread-local declaration of %q#D follows " - "non-thread-local declaration"; + return G_("thread-local declaration of %q#D follows " + "non-thread-local declaration"); else - return "non-thread-local declaration of %q#D follows " - "thread-local declaration"; + return G_("non-thread-local declaration of %q#D follows " + "thread-local declaration"); } else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl)) { @@ -2342,7 +2349,7 @@ redeclaration_error_message (tree newdecl, tree olddecl) is invalid. */ if ((TREE_CODE (newdecl) == VAR_DECL && DECL_ANON_UNION_VAR_P (newdecl)) || (TREE_CODE (olddecl) == VAR_DECL && DECL_ANON_UNION_VAR_P (olddecl))) - return "redeclaration of %q#D"; + return G_("redeclaration of %q#D"); /* If at least one declaration is a reference, there is no conflict. For example: @@ -2353,7 +2360,7 @@ redeclaration_error_message (tree newdecl, tree olddecl) if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl)) return NULL; /* Reject two definitions. */ - return "redefinition of %q#D"; + return G_("redefinition of %q#D"); } else { @@ -2361,7 +2368,7 @@ redeclaration_error_message (tree newdecl, tree olddecl) /* Reject two definitions, and reject a definition together with an external reference. */ if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))) - return "redeclaration of %q#D"; + return G_("redeclaration of %q#D"); return NULL; } } @@ -3039,11 +3046,11 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, if (!dependent_scope_p (context)) /* We should only set WANT_TYPE when we're a nested typename type. Then we can give better diagnostics if we find a non-type. */ - t = lookup_field (context, name, 0, /*want_type=*/true); + t = lookup_field (context, name, 2, /*want_type=*/true); else t = NULL_TREE; - if (!t && dependent_type_p (context)) + if ((!t || TREE_CODE (t) == TREE_LIST) && dependent_type_p (context)) return build_typename_type (context, name, fullname, tag_type); want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR; @@ -3056,6 +3063,20 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, return error_mark_node; } + /* Pull out the template from an injected-class-name (or multiple). */ + if (want_template) + t = maybe_get_template_decl_from_type_decl (t); + + if (TREE_CODE (t) == TREE_LIST) + { + if (complain & tf_error) + { + error ("lookup of %qT in %qT is ambiguous", name, context); + print_candidates (t); + } + return error_mark_node; + } + if (want_template && !DECL_CLASS_TEMPLATE_P (t)) { if (complain & tf_error) @@ -3074,6 +3095,11 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, if (complain & tf_error) perform_or_defer_access_check (TYPE_BINFO (context), t, t); + /* If we are currently parsing a template and if T is a typedef accessed + through CONTEXT then we need to remember and check access of T at + template instantiation time. */ + add_typedef_to_current_template_for_access_check (t, context, input_location); + if (want_template) return lookup_template_class (t, TREE_OPERAND (fullname, 1), NULL_TREE, context, @@ -3456,7 +3482,6 @@ cxx_init_decl_processing (void) bad_alloc_decl = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node); DECL_CONTEXT (bad_alloc_decl) = current_namespace; - TYPE_STUB_DECL (bad_alloc_type_node) = bad_alloc_decl; pop_namespace (); ptr_ftype_sizetype @@ -3939,6 +3964,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) "and functions"); else if (saw_typedef) warning (0, "% was ignored in this declaration"); + else if (declspecs->specs[(int) ds_constexpr]) + error ("% cannot be used for type declarations"); } return declared_type; @@ -4050,7 +4077,6 @@ start_decl (const cp_declarator *declarator, tree *pushed_scope_p) { tree decl; - tree type; tree context; bool was_public; int flags; @@ -4073,8 +4099,6 @@ start_decl (const cp_declarator *declarator, || decl == error_mark_node) return error_mark_node; - type = TREE_TYPE (decl); - context = DECL_CONTEXT (decl); if (context) @@ -4181,6 +4205,9 @@ start_decl (const cp_declarator *declarator, error ("duplicate initialization of %qD", decl); if (duplicate_decls (decl, field, /*newdecl_is_friend=*/false)) decl = field; + if (declspecs->specs[(int) ds_constexpr] + && !DECL_DECLARED_CONSTEXPR_P (field)) + error ("%qD declared % outside its class", field); } } else @@ -4219,6 +4246,9 @@ start_decl (const cp_declarator *declarator, if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)) permerror (input_location, "declaration of %q#D outside of class is not definition", decl); + + if (!ensure_literal_type_for_constexpr_object (decl)) + return error_mark_node; } was_public = TREE_PUBLIC (decl); @@ -4382,7 +4412,7 @@ 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); + tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error); if (tmp == error_mark_node) return NULL_TREE; @@ -4611,7 +4641,7 @@ maybe_commonize_var (tree decl) /* Don't mess with __FUNCTION__. */ && ! DECL_ARTIFICIAL (decl) && DECL_FUNCTION_SCOPE_P (decl) - && vague_linkage_fn_p (DECL_CONTEXT (decl))) + && vague_linkage_p (DECL_CONTEXT (decl))) { if (flag_weak) { @@ -4660,10 +4690,14 @@ check_for_uninitialized_const_var (tree decl) { tree type = TREE_TYPE (decl); + if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl) + && DECL_INITIAL (decl) == NULL) + error ("missing initializer for constexpr %qD", decl); + /* ``Unless explicitly declared extern, a const object does not have external linkage and must be initialized. ($8.4; $12.1)'' ARM 7.1.6 */ - if (TREE_CODE (decl) == VAR_DECL + else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (type) != REFERENCE_TYPE && CP_TYPE_CONST_P (type) && !TYPE_NEEDS_CONSTRUCTING (type) @@ -4688,7 +4722,7 @@ static tree reshape_init_r (tree, reshape_iter *, bool); initialized. If there are no more such fields, the return value will be NULL. */ -static tree +tree next_initializable_field (tree field) { while (field @@ -4852,6 +4886,9 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p) field_init = reshape_init_r (TREE_TYPE (field), d, /*first_initializer_p=*/false); + if (field_init == error_mark_node) + return error_mark_node; + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), field, field_init); /* [dcl.init.aggr] @@ -4900,7 +4937,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p) init = error_mark_node; } else - maybe_warn_cpp0x ("extended initializer lists"); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); } d->cur++; @@ -4921,7 +4958,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p) looking through the outermost braces; A a2 = { a1 }; is not a valid aggregate initialization. */ && !first_initializer_p - && can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL)) + && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init)) + || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL))) { d->cur++; return init; @@ -5143,7 +5181,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) { if (init_len == 0) { - maybe_warn_cpp0x ("extended initializer lists"); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); init = build_zero_init (type, NULL_TREE, false); } else if (init_len != 1) @@ -5573,23 +5611,27 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (init && TREE_CODE (decl) == FUNCTION_DECL) { + tree clone; if (init == ridpointers[(int)RID_DELETE]) { /* FIXME check this is 1st decl. */ DECL_DELETED_FN (decl) = 1; DECL_DECLARED_INLINE_P (decl) = 1; DECL_INITIAL (decl) = error_mark_node; + FOR_EACH_CLONE (clone, decl) + { + DECL_DELETED_FN (clone) = 1; + DECL_DECLARED_INLINE_P (clone) = 1; + DECL_INITIAL (clone) = error_mark_node; + } init = NULL_TREE; } else if (init == ridpointers[(int)RID_DEFAULT]) { - if (!defaultable_fn_p (decl)) - { - error ("%qD cannot be defaulted", decl); - DECL_INITIAL (decl) = NULL_TREE; - } - else + if (defaultable_fn_check (decl)) DECL_DEFAULTED_FN (decl) = 1; + else + DECL_INITIAL (decl) = NULL_TREE; } } @@ -5704,7 +5746,18 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (DECL_FUNCTION_SCOPE_P (decl) && TREE_STATIC (decl) && !DECL_ARTIFICIAL (decl)) - push_local_name (decl); + { + push_local_name (decl); + if (DECL_CONSTRUCTOR_P (current_function_decl) + || DECL_DESTRUCTOR_P (current_function_decl)) + /* Normally local_decls is populated during GIMPLE lowering, + but [cd]tors are never actually compiled directly. We need + to put statics on the list so we can deal with the label + address extension. */ + cfun->local_decls = tree_cons (NULL_TREE, decl, + cfun->local_decls); + } + /* Convert the initializer to the type of DECL, if we have not already initialized DECL. */ if (!DECL_INITIALIZED_P (decl) @@ -6622,6 +6675,7 @@ grokfndecl (tree ctype, { case sfk_constructor: case sfk_copy_constructor: + case sfk_move_constructor: DECL_CONSTRUCTOR_P (decl) = 1; break; case sfk_destructor: @@ -6678,7 +6732,7 @@ grokfndecl (tree ctype, } gcc_assert (TREE_CODE (fns) == IDENTIFIER_NODE || TREE_CODE (fns) == OVERLOAD); - DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE); + DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args); for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t)) if (TREE_PURPOSE (t) @@ -6750,6 +6804,38 @@ grokfndecl (tree ctype, || decl_function_context (TYPE_MAIN_DECL (ctype)))) publicp = 0; + if (publicp && cxx_dialect == cxx98) + { + /* [basic.link]: A name with no linkage (notably, the name of a class + or enumeration declared in a local scope) shall not be used to + declare an entity with linkage. + + DR 757 relaxes this restriction for C++0x. */ + t = no_linkage_check (TREE_TYPE (decl), + /*relaxed_p=*/false); + if (t) + { + if (TYPE_ANONYMOUS_P (t)) + { + if (DECL_EXTERN_C_P (decl)) + /* Allow this; it's pretty common in C. */; + else + { + permerror (input_location, "anonymous type with no linkage " + "used to declare function %q#D with linkage", + decl); + if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) + permerror (input_location, "%q+#D does not refer to the unqualified " + "type, so it is not used for linkage", + TYPE_NAME (t)); + } + } + else + permerror (input_location, "type %qT with no linkage used to " + "declare function %q#D with linkage", t, decl); + } + } + TREE_PUBLIC (decl) = publicp; if (! publicp) { @@ -6989,15 +7075,49 @@ grokvardecl (tree type, if (declspecs->specs[(int)ds_thread]) DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + /* If the type of the decl has no linkage, make sure that we'll + notice that in mark_used. */ + if (cxx_dialect > cxx98 + && decl_linkage (decl) != lk_none + && DECL_LANG_SPECIFIC (decl) == NULL + && !DECL_EXTERN_C_P (decl) + && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false)) + retrofit_lang_decl (decl); + if (TREE_PUBLIC (decl)) { - /* If the type of the decl has no linkage, make sure that we'll - notice that in mark_used. */ - if (DECL_LANG_SPECIFIC (decl) == NULL - && TREE_PUBLIC (decl) - && !DECL_EXTERN_C_P (decl) - && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false)) - retrofit_lang_decl (decl); + /* [basic.link]: A name with no linkage (notably, the name of a class + or enumeration declared in a local scope) shall not be used to + declare an entity with linkage. + + DR 757 relaxes this restriction for C++0x. */ + tree t = (cxx_dialect > cxx98 ? NULL_TREE + : no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false)); + if (t) + { + if (TYPE_ANONYMOUS_P (t)) + { + if (DECL_EXTERN_C_P (decl)) + /* Allow this; it's pretty common in C. */ + ; + else + { + /* DRs 132, 319 and 389 seem to indicate types with + no linkage can only be used to declare extern "C" + entities. Since it's not always an error in the + ISO C++ 90 Standard, we only issue a warning. */ + warning (0, "anonymous type with no linkage used to declare " + "variable %q#D with linkage", decl); + if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) + warning (0, "%q+#D does not refer to the unqualified " + "type, so it is not used for linkage", + TYPE_NAME (t)); + } + } + else + warning (0, "type %qT with no linkage used to declare variable " + "%q#D with linkage", t, decl); + } } else DECL_INTERFACE_KNOWN (decl) = 1; @@ -7089,16 +7209,9 @@ build_ptrmem_type (tree class_type, tree member_type) { if (TREE_CODE (member_type) == METHOD_TYPE) { - tree arg_types; - - arg_types = TYPE_ARG_TYPES (member_type); - class_type = (cp_build_qualified_type - (class_type, - cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types))))); - member_type - = build_method_type_directly (class_type, - TREE_TYPE (member_type), - TREE_CHAIN (arg_types)); + tree arg_types = TYPE_ARG_TYPES (member_type); + cp_cv_quals quals = cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types))); + member_type = build_memfn_type (member_type, class_type, quals); return build_ptrmemfunc_type (build_pointer_type (member_type)); } else @@ -7181,11 +7294,8 @@ compute_array_index_type (tree name, tree size) structural equality checks. */ itype = build_index_type (build_min (MINUS_EXPR, sizetype, size, integer_one_node)); - if (!TREE_SIDE_EFFECTS (size)) - { - TYPE_DEPENDENT_P (itype) = 1; - TYPE_DEPENDENT_P_VALID (itype) = 1; - } + TYPE_DEPENDENT_P (itype) = 1; + TYPE_DEPENDENT_P_VALID (itype) = 1; SET_TYPE_STRUCTURAL_EQUALITY (itype); return itype; } @@ -7334,47 +7444,45 @@ static tree create_array_type_for_decl (tree name, tree type, tree size) { tree itype = NULL_TREE; - const char* error_msg; /* If things have already gone awry, bail now. */ if (type == error_mark_node || size == error_mark_node) return error_mark_node; - /* Assume that everything will go OK. */ - error_msg = NULL; - - /* There are some types which cannot be array elements. */ + /* If there are some types which cannot be array elements, + issue an error-message and return. */ switch (TREE_CODE (type)) { case VOID_TYPE: - error_msg = "array of void"; - break; + if (name) + error ("declaration of %qD as array of void", name); + else + error ("creating array of void"); + return error_mark_node; case FUNCTION_TYPE: - error_msg = "array of functions"; - break; + if (name) + error ("declaration of %qD as array of functions", name); + else + error ("creating array of functions"); + return error_mark_node; case REFERENCE_TYPE: - error_msg = "array of references"; - break; + if (name) + error ("declaration of %qD as array of references", name); + else + error ("creating array of references"); + return error_mark_node; case METHOD_TYPE: - error_msg = "array of function members"; - break; - - default: - break; - } - - /* If something went wrong, issue an error-message and return. */ - if (error_msg) - { if (name) - error ("declaration of %qD as %s", name, error_msg); + error ("declaration of %qD as array of function members", name); else - error ("creating %s", error_msg); - + error ("creating array of function members"); return error_mark_node; + + default: + break; } /* [dcl.array] @@ -7500,11 +7608,13 @@ check_var_type (tree identifier, tree type) try to parse. PARM for a parameter declaration (either within a function prototype or before a function body). Make a PARM_DECL, or return void_type_node. + TPARM for a template parameter declaration. CATCHPARM for a parameter declaration before a catch clause. TYPENAME if for a typename (in a cast or sizeof). Don't make a DECL node; just return the ..._TYPE node. FIELD for a struct or union field; make a FIELD_DECL. BITFIELD for a field with specified width. + INITIALIZED is as for start_decl. ATTRLIST is a pointer to the list of attributes, which may be NULL @@ -7588,6 +7698,8 @@ grokdeclarator (const cp_declarator *declarator, bool type_was_error_mark_node = false; bool parameter_pack_p = declarator? declarator->parameter_pack_p : false; bool template_type_arg = false; + bool template_parm_flag = false; + bool constexpr_p = declspecs->specs[(int) ds_constexpr]; const char *errmsg; signed_p = declspecs->specs[(int)ds_signed]; @@ -7605,6 +7717,8 @@ grokdeclarator (const cp_declarator *declarator, bitfield = 1, decl_context = FIELD; else if (decl_context == TEMPLATE_TYPE_ARG) template_type_arg = true, decl_context = TYPENAME; + else if (decl_context == TPARM) + template_parm_flag = true, decl_context = PARM; if (initialized > 1) funcdef_flag = true; @@ -8032,6 +8146,17 @@ grokdeclarator (const cp_declarator *declarator, type_quals = TYPE_UNQUALIFIED; if (declspecs->specs[(int)ds_const]) type_quals |= TYPE_QUAL_CONST; + /* A `constexpr' specifier used in an object declaration declares + the object as `const'. */ + if (constexpr_p) + { + if (innermost_code == cdk_function) + ; + else if (declspecs->specs[(int)ds_const] != 0) + error ("both % and % cannot be used here"); + else + type_quals |= TYPE_QUAL_CONST; + } if (declspecs->specs[(int)ds_volatile]) type_quals |= TYPE_QUAL_VOLATILE; if (declspecs->specs[(int)ds_restrict]) @@ -8046,7 +8171,7 @@ grokdeclarator (const cp_declarator *declarator, /* This was an error in C++98 (cv-qualifiers cannot be added to a function type), but DR 295 makes the code well-formed by dropping the extra qualifiers. */ - if (pedantic) + if (pedantic && cxx_dialect == cxx98) { tree bad_type = build_qualified_type (type, type_quals); pedwarn (input_location, OPT_pedantic, @@ -8093,6 +8218,11 @@ grokdeclarator (const cp_declarator *declarator, error ("typedef declaration invalid in parameter declaration"); return error_mark_node; } + else if (template_parm_flag && storage_class != sc_none) + { + error ("storage class specified for template parameter %qs", name); + return error_mark_node; + } else if (storage_class == sc_static || storage_class == sc_extern || thread_p) @@ -8103,6 +8233,14 @@ grokdeclarator (const cp_declarator *declarator, error ("parameter declared %"); type = error_mark_node; } + + /* Function parameters cannot be constexpr. If we saw one, moan + and pretend it wasn't there. */ + if (constexpr_p) + { + error ("a parameter cannot be declared %"); + constexpr_p = 0; + } } /* Give error if `virtual' is used outside of class declaration. */ @@ -8405,11 +8543,26 @@ grokdeclarator (const cp_declarator *declarator, { if (explicitp == 1) { - maybe_warn_cpp0x ("explicit conversion operators"); + maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION); explicitp = 2; } } + /* It is not allowed to use `constexpr' in a function + declaration that is not a definition. + That is too strict, though. */ + if (constexpr_p && !funcdef_flag) + { + error ("the % specifier cannot be used in " + "a function declaration that is not a definition"); + constexpr_p = false; + } + + /* A constexpr non-static member function is implicitly const. */ + if (constexpr_p && decl_context == FIELD && staticp == 0 + && sfk != sfk_constructor && sfk != sfk_destructor) + memfn_quals |= TYPE_QUAL_CONST; + arg_types = grokparms (declarator->u.function.parameters, &parms); @@ -8479,8 +8632,9 @@ grokdeclarator (const cp_declarator *declarator, if (TREE_CODE (type) == FUNCTION_TYPE && cp_type_quals (type) != TYPE_UNQUALIFIED) - error ("cannot declare %s to qualified function type %qT", - declarator->kind == cdk_reference ? "reference" : "pointer", + error (declarator->kind == cdk_reference + ? G_("cannot declare reference to qualified function type %qT") + : G_("cannot declare pointer to qualified function type %qT"), type); if (declarator->kind == cdk_reference) @@ -8654,6 +8808,12 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } + /* It is not permitted to define a member function outside ist + membership class as `constexpr'. */ + if (constexpr_p) + error ("a constexpr function cannot be defined " + "outside of its class"); + if (TREE_CODE (sname) == IDENTIFIER_NODE && NEW_DELETE_OPNAME_P (sname)) /* Overloaded operator new and operator delete @@ -8878,7 +9038,9 @@ grokdeclarator (const cp_declarator *declarator, tree decls = NULL_TREE; tree args; - for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args)) + for (args = TYPE_ARG_TYPES (type); + args && args != void_list_node; + args = TREE_CHAIN (args)) { tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args)); @@ -8906,6 +9068,7 @@ grokdeclarator (const cp_declarator *declarator, /* The qualifiers on the function type become the qualifiers on the non-static member function. */ memfn_quals |= cp_type_quals (type); + type_quals = TYPE_UNQUALIFIED; } } @@ -9121,6 +9284,8 @@ grokdeclarator (const cp_declarator *declarator, uqname, ctype); return error_mark_node; } + if (constexpr_p) + error ("a destructor cannot be %"); } else if (sfk == sfk_constructor && friendp) { @@ -9141,7 +9306,8 @@ grokdeclarator (const cp_declarator *declarator, parms, unqualified_id, virtualp, flags, memfn_quals, raises, - friendp ? -1 : 0, friendp, publicp, inlinep, + friendp ? -1 : 0, friendp, publicp, + inlinep || constexpr_p, sfk, funcdef_flag, template_count, in_namespace, attrlist, declarator->id_loc); @@ -9230,6 +9396,7 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } + DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p; decl = do_friend (ctype, unqualified_id, decl, *attrlist, flags, funcdef_flag); @@ -9294,6 +9461,9 @@ grokdeclarator (const cp_declarator *declarator, } else { + if (constexpr_p) + error ("non-static data member %qE declared %", + unqualified_id); decl = build_decl (input_location, FIELD_DECL, unqualified_id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; @@ -9388,7 +9558,7 @@ grokdeclarator (const cp_declarator *declarator, decl = grokfndecl (ctype, type, original_name, parms, unqualified_id, virtualp, flags, memfn_quals, raises, 1, friendp, - publicp, inlinep, sfk, funcdef_flag, + publicp, inlinep || constexpr_p, sfk, funcdef_flag, template_count, in_namespace, attrlist, declarator->id_loc); if (decl == NULL_TREE) @@ -9485,6 +9655,10 @@ grokdeclarator (const cp_declarator *declarator, else if (storage_class == sc_static) DECL_THIS_STATIC (decl) = 1; + /* Don't forget constexprness. */ + if (VAR_OR_FUNCTION_DECL_P (decl)) + DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p; + /* Record constancy and volatility on the DECL itself . There's no need to do this when processing a template; we'll do this for the instantiated declaration based on the type of DECL. */ @@ -9632,6 +9806,10 @@ type_is_deprecated (tree type) && TREE_DEPRECATED (TYPE_NAME (type))) return type; + /* Do warn about using typedefs to a deprecated class. */ + if (TAGGED_TYPE_P (type) && type != TYPE_MAIN_VARIANT (type)) + return type_is_deprecated (TYPE_MAIN_VARIANT (type)); + code = TREE_CODE (type); if (code == POINTER_TYPE || code == REFERENCE_TYPE @@ -9748,9 +9926,12 @@ grokparms (tree parmlist, tree *parms) t = TREE_TYPE (t); } if (TREE_CODE (t) == ARRAY_TYPE) - error ("parameter %qD includes %s to array of unknown " - "bound %qT", - decl, ptr ? "pointer" : "reference", t); + error (ptr + ? G_("parameter %qD includes pointer to array of " + "unknown bound %qT") + : G_("parameter %qD includes reference to array of " + "unknown bound %qT"), + decl, t); } if (any_error) @@ -9789,9 +9970,9 @@ grokparms (tree parmlist, tree *parms) 0 if D is not a copy constructor or copy assignment operator. 1 if D is a copy constructor or copy assignment operator whose - first parameter is a reference to const qualified T. - 2 if D is a copy constructor or copy assignment operator whose first parameter is a reference to non-const qualified T. + 2 if D is a copy constructor or copy assignment operator whose + first parameter is a reference to const qualified T. This function can be used as a predicate. Positive values indicate a copy constructor and nonzero values indicate a copy assignment @@ -9926,7 +10107,7 @@ grok_special_member_properties (tree decl) are no other parameters or else all other parameters have default arguments. */ TYPE_HAS_INIT_REF (class_type) = 1; - if (!DECL_DEFAULTED_FN (decl)) + if (user_provided_p (decl)) TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1; if (ctor > 1) TYPE_HAS_CONST_INIT_REF (class_type) = 1; @@ -9934,7 +10115,7 @@ grok_special_member_properties (tree decl) else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl))) { TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1; - if (TREE_CODE (decl) == TEMPLATE_DECL || !DECL_DEFAULTED_FN (decl)) + if (user_provided_p (decl)) TYPE_HAS_COMPLEX_DFLT (class_type) = 1; } else if (is_list_ctor (decl)) @@ -9953,7 +10134,7 @@ grok_special_member_properties (tree decl) if (assop) { TYPE_HAS_ASSIGN_REF (class_type) = 1; - if (!DECL_DEFAULTED_FN (decl)) + if (user_provided_p (decl)) TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1; if (assop != 1) TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1; @@ -10192,28 +10373,38 @@ grok_op_properties (tree decl, bool complain) { tree t = TREE_TYPE (name); int ref = (TREE_CODE (t) == REFERENCE_TYPE); - const char *what = 0; if (ref) t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); if (TREE_CODE (t) == VOID_TYPE) - what = "void"; + warning (OPT_Wconversion, + ref + ? G_("conversion to a reference to void " + "will never use a type conversion operator") + : G_("conversion to void " + "will never use a type conversion operator")); else if (class_type) { if (t == class_type) - what = "the same type"; + warning (OPT_Wconversion, + ref + ? G_("conversion to a reference to the same type " + "will never use a type conversion operator") + : G_("conversion to the same type " + "will never use a type conversion operator")); /* Don't force t to be complete here. */ else if (MAYBE_CLASS_TYPE_P (t) && COMPLETE_TYPE_P (t) && DERIVED_FROM_P (t, class_type)) - what = "a base class"; + warning (OPT_Wconversion, + ref + ? G_("conversion to a reference to a base class " + "will never use a type conversion operator") + : G_("conversion to a base class " + "will never use a type conversion operator")); } - if (what) - warning (OPT_Wconversion, "conversion to %s%s will never use a type " - "conversion operator", - ref ? "a reference to " : "", what); } if (operator_code == COND_EXPR) @@ -10448,6 +10639,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, elaborated type specifier is the implicit typedef created when the type is declared. */ else if (!DECL_IMPLICIT_TYPEDEF_P (decl) + && !DECL_SELF_REFERENCE_P (decl) && tag_code != typename_type) { error ("using typedef-name %qD after %qs", decl, tag_name (tag_code)); @@ -10981,7 +11173,7 @@ start_enum (tree name, tree underlying_type, bool scoped_enum_p) if (enumtype == error_mark_node) name = make_anon_name (); - enumtype = make_node (ENUMERAL_TYPE); + enumtype = cxx_make_type (ENUMERAL_TYPE); enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current); } @@ -11413,7 +11605,7 @@ lookup_enumerator (tree enumtype, tree name) } -/* We're defining DECL. Make sure that it's type is OK. */ +/* We're defining DECL. Make sure that its type is OK. */ static void check_function_type (tree decl, tree current_function_parms) @@ -11424,6 +11616,10 @@ check_function_type (tree decl, tree current_function_parms) /* In a function definition, arg types must be complete. */ require_complete_types_for_parms (current_function_parms); + /* constexpr functions must have literal argument types and + literal return type. */ + validate_constexpr_fundecl (decl); + if (dependent_type_p (return_type)) return; if (!COMPLETE_OR_VOID_TYPE_P (return_type) @@ -11443,9 +11639,12 @@ check_function_type (tree decl, tree current_function_parms) TREE_CHAIN (args)); else fntype = build_function_type (void_type_node, args); - TREE_TYPE (decl) + fntype = build_exception_variant (fntype, TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl))); + fntype = (cp_build_type_attribute_variant + (fntype, TYPE_ATTRIBUTES (TREE_TYPE (decl)))); + TREE_TYPE (decl) = fntype; } else abstract_virtuals_error (decl, TREE_TYPE (fntype)); @@ -11730,7 +11929,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) gcc_assert (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE); cp_function_chain->x_current_class_ref - = cp_build_indirect_ref (t, NULL, tf_warning_or_error); + = cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error); cp_function_chain->x_current_class_ptr = t; /* Constructors and destructors need to know whether they're "in @@ -12352,6 +12551,8 @@ finish_function (int flags) && !current_function_returns_value && !current_function_returns_null /* Don't complain if we abort or throw. */ && !current_function_returns_abnormally + /* Don't complain if we are declared noreturn. */ + && !TREE_THIS_VOLATILE (fndecl) && !DECL_NAME (DECL_RESULT (fndecl)) && !TREE_NO_WARNING (fndecl) /* Structor return values (if any) are set by the compiler. */ @@ -12371,7 +12572,7 @@ finish_function (int flags) if (!processing_template_decl) { struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl); - invoke_plugin_callbacks (PLUGIN_CXX_CP_PRE_GENERICIZE, fndecl); + invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl); cp_genericize (fndecl); /* Clear out the bits we don't need. */ f->x_current_class_ptr = NULL; @@ -12645,26 +12846,47 @@ finish_stmt (void) { } +/* Return the FUNCTION_TYPE that corresponds to MEMFNTYPE, which can be a + FUNCTION_DECL, METHOD_TYPE, FUNCTION_TYPE, pointer or reference to + METHOD_TYPE or FUNCTION_TYPE, or pointer to member function. */ + +tree +static_fn_type (tree memfntype) +{ + tree fntype; + tree args; + int quals; + + if (TYPE_PTRMEMFUNC_P (memfntype)) + memfntype = TYPE_PTRMEMFUNC_FN_TYPE (memfntype); + if (POINTER_TYPE_P (memfntype) + || TREE_CODE (memfntype) == FUNCTION_DECL) + memfntype = TREE_TYPE (memfntype); + if (TREE_CODE (memfntype) == FUNCTION_TYPE) + return memfntype; + gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE); + args = TYPE_ARG_TYPES (memfntype); + fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args)); + quals = cp_type_quals (TREE_TYPE (TREE_VALUE (args))); + fntype = build_qualified_type (fntype, quals); + fntype = (cp_build_type_attribute_variant + (fntype, TYPE_ATTRIBUTES (memfntype))); + fntype = (build_exception_variant + (fntype, TYPE_RAISES_EXCEPTIONS (memfntype))); + return fntype; +} + /* DECL was originally constructed as a non-static member function, but turned out to be static. Update it accordingly. */ void revert_static_member_fn (tree decl) { - tree tmp; - tree function = TREE_TYPE (decl); - tree args = TYPE_ARG_TYPES (function); + TREE_TYPE (decl) = static_fn_type (decl); - if (cp_type_quals (TREE_TYPE (TREE_VALUE (args))) - != TYPE_UNQUALIFIED) + if (cp_type_quals (TREE_TYPE (decl)) != TYPE_UNQUALIFIED) error ("static member function %q#D declared with type qualifiers", decl); - args = TREE_CHAIN (args); - tmp = build_function_type (TREE_TYPE (function), args); - tmp = build_qualified_type (tmp, cp_type_quals (function)); - tmp = build_exception_variant (tmp, - TYPE_RAISES_EXCEPTIONS (function)); - TREE_TYPE (decl) = tmp; if (DECL_ARGUMENTS (decl)) DECL_ARGUMENTS (decl) = TREE_CHAIN (DECL_ARGUMENTS (decl)); DECL_STATIC_FUNCTION_P (decl) = 1; @@ -12687,6 +12909,8 @@ cp_tree_node_structure (union lang_tree_node * t) case STATIC_ASSERT: return TS_CP_STATIC_ASSERT; case ARGUMENT_PACK_SELECT: return TS_CP_ARGUMENT_PACK_SELECT; case TRAIT_EXPR: return TS_CP_TRAIT_EXPR; + case LAMBDA_EXPR: return TS_CP_LAMBDA_EXPR; + case TEMPLATE_INFO: return TS_CP_TEMPLATE_INFO; default: return TS_CP_GENERIC; } }