X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl.c;h=eed45352871a99b02902dc96559c9207a51633dc;hb=190130f10c6b8a9d5c9980ab924111b5cb4e0483;hp=b8435a6ddaa265091113df53a4373037f7ef3b57;hpb=5e260adbb1f177a25a39691d3e4510d6bc3b898a;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b8435a6ddaa..eed45352871 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -184,7 +184,7 @@ struct GTY((chain_next ("%h.next"))) named_label_use_entry { /* The binding level to which this entry is *currently* attached. This is initially the binding level in which the goto appeared, but is modified as scopes are closed. */ - struct cp_binding_level *binding_level; + cp_binding_level *binding_level; /* The head of the names list that was current when the goto appeared, or the inner scope popped. These are the decls that will *not* be skipped when jumping to the label. */ @@ -208,7 +208,7 @@ struct GTY(()) named_label_entry { /* The binding level to which the label is *currently* attached. This is initially set to the binding level in which the label is defined, but is modified as scopes are closed. */ - struct cp_binding_level *binding_level; + cp_binding_level *binding_level; /* The head of the names list that was current when the label was defined, or the inner scope popped. These are the decls that will be skipped when jumping to the label. */ @@ -270,7 +270,7 @@ current_tmpl_spec_kind (int n_class_scopes) int n_template_parm_scopes = 0; int seen_specialization_p = 0; int innermost_specialization_p = 0; - struct cp_binding_level *b; + cp_binding_level *b; /* Scan through the template parameter scopes. */ for (b = current_binding_level; @@ -447,7 +447,7 @@ objc_get_current_scope (void) void objc_mark_locals_volatile (void *enclosing_blk) { - struct cp_binding_level *scope; + cp_binding_level *scope; for (scope = current_binding_level; scope && scope != enclosing_blk; @@ -470,8 +470,8 @@ static int poplevel_named_label_1 (void **slot, void *data) { struct named_label_entry *ent = (struct named_label_entry *) *slot; - struct cp_binding_level *bl = (struct cp_binding_level *) data; - struct cp_binding_level *obl = bl->level_chain; + cp_binding_level *bl = (cp_binding_level *) data; + cp_binding_level *obl = bl->level_chain; if (ent->binding_level == bl) { @@ -643,6 +643,9 @@ poplevel (int keep, int reverse, int functionbody) for (link = decls; link; link = TREE_CHAIN (link)) { if (leaving_for_scope && TREE_CODE (link) == VAR_DECL + /* It's hard to make this ARM compatibility hack play nicely with + lambdas, and it really isn't necessary in C++11 mode. */ + && cxx_dialect < cxx0x && DECL_NAME (link)) { tree name = DECL_NAME (link); @@ -853,7 +856,7 @@ walk_namespaces (walk_namespaces_fn f, void* data) int wrapup_globals_for_namespace (tree name_space, void* data) { - struct cp_binding_level *level = NAMESPACE_LEVEL (name_space); + cp_binding_level *level = NAMESPACE_LEVEL (name_space); VEC(tree,gc) *statics = level->static_decls; tree *vec = VEC_address (tree, statics); int len = VEC_length (tree, statics); @@ -2644,10 +2647,10 @@ identify_goto (tree decl, const location_t *locus) true if all is well. */ static bool -check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names, +check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, bool exited_omp, const location_t *locus) { - struct cp_binding_level *b; + cp_binding_level *b; bool identified = false, saw_eh = false, saw_omp = false; if (exited_omp) @@ -2719,7 +2722,7 @@ check_previous_goto (tree decl, struct named_label_use_entry *use) } static bool -check_switch_goto (struct cp_binding_level* level) +check_switch_goto (cp_binding_level* level) { return check_previous_goto_1 (NULL_TREE, level, level->names, false, NULL); } @@ -2805,7 +2808,7 @@ check_goto (tree decl) error (" enters OpenMP structured block"); else if (flag_openmp) { - struct cp_binding_level *b; + cp_binding_level *b; for (b = current_binding_level; b ; b = b->level_chain) { if (b == ent->binding_level) @@ -2831,7 +2834,7 @@ check_goto (tree decl) bool check_omp_return (void) { - struct cp_binding_level *b; + cp_binding_level *b; for (b = current_binding_level; b ; b = b->level_chain) if (b->kind == sk_omp) { @@ -2850,7 +2853,7 @@ static tree define_label_1 (location_t location, tree name) { struct named_label_entry *ent, dummy; - struct cp_binding_level *p; + cp_binding_level *p; tree decl; decl = lookup_label (name); @@ -2909,7 +2912,7 @@ define_label (location_t location, tree name) struct cp_switch { - struct cp_binding_level *level; + cp_binding_level *level; struct cp_switch *next; /* The SWITCH_STMT being built. */ tree switch_stmt; @@ -2990,7 +2993,7 @@ tree finish_case_label (location_t loc, tree low_value, tree high_value) { tree cond, r; - struct cp_binding_level *p; + cp_binding_level *p; tree type; if (processing_template_decl) @@ -3518,8 +3521,6 @@ cxx_init_decl_processing (void) tree void_ftype; tree void_ftype_ptr; - build_common_tree_nodes (flag_signed_char); - /* Create all the identifiers we need. */ initialize_predefined_identifiers (); @@ -3536,8 +3537,6 @@ cxx_init_decl_processing (void) TREE_PUBLIC (global_namespace) = 1; begin_scope (sk_namespace, global_namespace); - current_lang_name = NULL_TREE; - if (flag_visibility_ms_compat) default_visibility = VISIBILITY_HIDDEN; @@ -3601,6 +3600,10 @@ cxx_init_decl_processing (void) init_list_type_node = make_node (LANG_TYPE); record_unknown_type (init_list_type_node, "init list"); + dependent_lambda_return_type_node = make_node (LANG_TYPE); + record_unknown_type (dependent_lambda_return_type_node, + "undeduced lambda return type"); + { /* Make sure we get a unique function type, so we can give its pointer type a name. (This wins for gdb.) */ @@ -3633,6 +3636,7 @@ cxx_init_decl_processing (void) current_lang_name = lang_name_cplusplus; { + tree newattrs; tree newtype, deltype; tree ptr_ftype_sizetype; tree new_eh_spec; @@ -3660,7 +3664,13 @@ cxx_init_decl_processing (void) else new_eh_spec = noexcept_false_spec; - newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec); + /* Ensure attribs.c is initialized. */ + init_attributes (); + newattrs + = build_tree_list (get_identifier ("alloc_size"), + build_tree_list (NULL_TREE, integer_one_node)); + newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs); + newtype = build_exception_variant (newtype, new_eh_spec); deltype = build_exception_variant (void_ftype_ptr, empty_except_spec); push_cp_library_fn (NEW_EXPR, newtype); push_cp_library_fn (VEC_NEW_EXPR, newtype); @@ -3762,7 +3772,7 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep) if (current_function_decl) { - struct cp_binding_level *b = current_binding_level; + cp_binding_level *b = current_binding_level; if (b->kind == sk_function_parms) return error_mark_node; while (b->level_chain->kind != sk_function_parms) @@ -4594,6 +4604,12 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) explicitly); we need to allow the temporary to be initialized first. */ tmp = initialize_reference (type, init, decl, cleanup, 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; @@ -4652,7 +4668,8 @@ build_init_list_var_init (tree decl, tree type, tree init, tree *array_init, is valid, i.e., does not have a designated initializer. */ static bool -check_array_designated_initializer (const constructor_elt *ce) +check_array_designated_initializer (const constructor_elt *ce, + unsigned HOST_WIDE_INT index) { /* Designated initializers for array elements are not supported. */ if (ce->index) @@ -4663,8 +4680,13 @@ check_array_designated_initializer (const constructor_elt *ce) error ("name used in a GNU-style designated " "initializer for an array"); else if (TREE_CODE (ce->index) == INTEGER_CST) - /* An index added by reshape_init. */ - return true; + { + /* A C99 designator is OK if it matches the current index. */ + if (TREE_INT_CST_LOW (ce->index) == index) + return true; + else + sorry ("non-trivial designated initializers not supported"); + } else { gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE); @@ -4706,7 +4728,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init) constructor_elt *ce; HOST_WIDE_INT i; FOR_EACH_VEC_ELT (constructor_elt, v, i, ce) - if (!check_array_designated_initializer (ce)) + if (!check_array_designated_initializer (ce, i)) failure = 1; } @@ -4965,7 +4987,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d, { tree elt_init; - check_array_designated_initializer (d->cur); + check_array_designated_initializer (d->cur, index); elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false, complain); if (elt_init == error_mark_node) @@ -5917,7 +5939,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, cleanup = NULL_TREE; /* If a name was specified, get the string. */ - if (global_scope_p (current_binding_level)) + if (at_namespace_scope_p ()) asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); if (asmspec_tree && asmspec_tree != error_mark_node) asmspec = TREE_STRING_POINTER (asmspec_tree); @@ -6302,6 +6324,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (was_readonly) TREE_READONLY (decl) = 1; + + invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl); } /* Returns a declaration for a VAR_DECL as if: @@ -6650,7 +6674,6 @@ expand_static_init (tree decl, tree init) tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE; tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE; tree guard, guard_addr; - tree acquire_fn, release_fn, abort_fn; tree flag, begin; /* Emit code to perform this initialization but once. This code @@ -6700,29 +6723,31 @@ expand_static_init (tree decl, tree init) if (flag_threadsafe_statics) { + tree vfntype = NULL_TREE; + tree acquire_name, release_name, abort_name; + tree acquire_fn, release_fn, abort_fn; guard_addr = build_address (guard); - acquire_fn = get_identifier ("__cxa_guard_acquire"); - release_fn = get_identifier ("__cxa_guard_release"); - abort_fn = get_identifier ("__cxa_guard_abort"); - if (!get_global_value_if_present (acquire_fn, &acquire_fn)) - { - tree vfntype = build_function_type_list (void_type_node, - TREE_TYPE (guard_addr), - NULL_TREE); - acquire_fn = push_library_fn - (acquire_fn, build_function_type_list (integer_type_node, + acquire_name = get_identifier ("__cxa_guard_acquire"); + release_name = get_identifier ("__cxa_guard_release"); + abort_name = get_identifier ("__cxa_guard_abort"); + acquire_fn = identifier_global_value (acquire_name); + release_fn = identifier_global_value (release_name); + abort_fn = identifier_global_value (abort_name); + if (!acquire_fn) + acquire_fn = push_library_fn + (acquire_name, build_function_type_list (integer_type_node, TREE_TYPE (guard_addr), NULL_TREE), - NULL_TREE); - release_fn = push_library_fn (release_fn, vfntype, NULL_TREE); - abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE); - } - else - { - release_fn = identifier_global_value (release_fn); - abort_fn = identifier_global_value (abort_fn); - } + NULL_TREE); + if (!release_fn || !abort_fn) + vfntype = build_function_type_list (void_type_node, + TREE_TYPE (guard_addr), + NULL_TREE); + if (!release_fn) + release_fn = push_library_fn (release_name, vfntype, NULL_TREE); + if (!abort_fn) + abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE); inner_if_stmt = begin_if_stmt (); finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr), @@ -7001,7 +7026,14 @@ build_this_parm (tree type, cp_cv_quals quals) tree parm; cp_cv_quals this_quals; - this_type = type_of_this_parm (type); + if (CLASS_TYPE_P (type)) + { + this_type + = cp_build_qualified_type (type, quals & ~TYPE_QUAL_RESTRICT); + this_type = build_pointer_type (this_type); + } + else + this_type = type_of_this_parm (type); /* The `this' parameter is implicitly `const'; it cannot be assigned to. */ this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST; @@ -8495,7 +8527,7 @@ grokdeclarator (const cp_declarator *declarator, if (decl_context == NORMAL && !toplevel_bindings_p ()) { - struct cp_binding_level *b = current_binding_level; + cp_binding_level *b = current_binding_level; current_binding_level = b->level_chain; if (current_binding_level != 0 && toplevel_bindings_p ()) decl_context = PARM; @@ -9611,6 +9643,7 @@ grokdeclarator (const cp_declarator *declarator, && TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && TYPE_ANONYMOUS_P (type) + && declspecs->type_definition_p && cp_type_quals (type) == TYPE_UNQUALIFIED) { tree t; @@ -12432,7 +12465,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) tree fntype; tree restype; int doing_friend = 0; - struct cp_binding_level *bl; + cp_binding_level *bl; tree current_function_parms; struct c_fileinfo *finfo = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1))); @@ -12626,10 +12659,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags) maybe_apply_pragma_weak (decl1); } - /* constexpr functions must have literal argument types and - literal return type. */ - validate_constexpr_fundecl (decl1); - /* Reset this in case the call to pushdecl changed it. */ current_function_decl = decl1; @@ -12675,6 +12704,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) cp_function_chain->x_current_class_ref = cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error); + /* Set this second to avoid shortcut in cp_build_indirect_ref. */ cp_function_chain->x_current_class_ptr = t; /* Constructors and destructors need to know whether they're "in @@ -13209,22 +13239,13 @@ finish_function (int flags) { if (DECL_MAIN_P (current_function_decl)) { - tree stmt; - /* Make it so that `main' always returns 0 by default (or 1 for VMS). */ #if VMS_TARGET - stmt = finish_return_stmt (integer_one_node); + finish_return_stmt (integer_one_node); #else - stmt = finish_return_stmt (integer_zero_node); + finish_return_stmt (integer_zero_node); #endif - /* Hack. We don't want the middle-end to warn that this - return is unreachable, so put the statement on the - special line 0. */ - { - location_t linezero = linemap_line_start (line_table, 0, 1); - SET_EXPR_LOCATION (stmt, linezero); - } } if (use_eh_spec_block (current_function_decl))