X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl2.c;h=468c904710c1f499fd60754cbf5497e1d1eccf35;hb=9282d1690a7f7f23f2466f43e81a954feabb7da9;hp=7c3f7c058d6ad5130957593f9743ae1ef91aabec;hpb=6ffc789029e5aae506c9c5aaec2bf2a188eb9613;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 7c3f7c058d6..468c904710c 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C++ compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) @@ -33,26 +33,27 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "rtl.h" -#include "expr.h" #include "flags.h" #include "cp-tree.h" #include "decl.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "timevar.h" #include "cpplib.h" #include "target.h" -#include "c-common.h" +#include "c-family/c-common.h" +#include "c-family/c-objc.h" #include "tree-mudflap.h" #include "cgraph.h" #include "tree-inline.h" -#include "c-pragma.h" +#include "c-family/c-pragma.h" #include "tree-dump.h" #include "intl.h" #include "gimple.h" #include "pointer-set.h" +#include "splay-tree.h" +#include "langhooks.h" +#include "c-family/c-ada-spec.h" extern cpp_reader *parse_in; @@ -139,6 +140,37 @@ build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals) return fntype; } +/* Return a variant of FNTYPE, a FUNCTION_TYPE or METHOD_TYPE, with its + return type changed to NEW_RET. */ + +tree +change_return_type (tree new_ret, tree fntype) +{ + tree newtype; + tree args = TYPE_ARG_TYPES (fntype); + tree raises = TYPE_RAISES_EXCEPTIONS (fntype); + tree attrs = TYPE_ATTRIBUTES (fntype); + + if (same_type_p (new_ret, TREE_TYPE (fntype))) + return fntype; + + if (TREE_CODE (fntype) == FUNCTION_TYPE) + { + newtype = build_function_type (new_ret, args); + newtype = apply_memfn_quals (newtype, type_memfn_quals (fntype)); + } + else + newtype = build_method_type_directly + (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), + new_ret, TREE_CHAIN (args)); + if (raises) + newtype = build_exception_variant (newtype, raises); + if (attrs) + newtype = cp_build_type_attribute_variant (newtype, attrs); + + return newtype; +} + /* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE appropriately. */ @@ -211,7 +243,7 @@ maybe_retrofit_in_chrg (tree fn) basetype = TREE_TYPE (TREE_VALUE (arg_types)); arg_types = TREE_CHAIN (arg_types); - parms = TREE_CHAIN (DECL_ARGUMENTS (fn)); + parms = DECL_CHAIN (DECL_ARGUMENTS (fn)); /* If this is a subobject constructor or destructor, our caller will pass us a pointer to our VTT. */ @@ -220,7 +252,7 @@ maybe_retrofit_in_chrg (tree fn) parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type); /* First add it to DECL_ARGUMENTS between 'this' and the real args... */ - TREE_CHAIN (parm) = parms; + DECL_CHAIN (parm) = parms; parms = parm; /* ...and then to TYPE_ARG_TYPES. */ @@ -231,12 +263,12 @@ maybe_retrofit_in_chrg (tree fn) /* Then add the in-charge parm (before the VTT parm). */ parm = build_artificial_parm (in_charge_identifier, integer_type_node); - TREE_CHAIN (parm) = parms; + DECL_CHAIN (parm) = parms; parms = parm; arg_types = hash_tree_chain (integer_type_node, arg_types); /* Insert our new parameter(s) into the list. */ - TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms; + DECL_CHAIN (DECL_ARGUMENTS (fn)) = parms; /* And rebuild the function type. */ fntype = build_method_type_directly (basetype, TREE_TYPE (TREE_TYPE (fn)), @@ -593,7 +625,7 @@ check_classfn (tree ctype, tree function, tree template_parms) && !comp_template_parms (template_parms, DECL_TEMPLATE_PARMS (function))) { - error ("template parameter lists provided don't match the " + error ("template parameter lists provided don%'t match the " "template parameters of %qD", function); return error_mark_node; } @@ -740,23 +772,12 @@ finish_static_data_member_decl (tree decl, permerror (input_location, "local class %q#T shall not have static data member %q#D", current_class_type, decl); - /* Static consts need not be initialized in the class definition. */ - if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) - { - static int explained = 0; - - error ("initializer invalid for static member with constructor"); - if (!explained) - { - error ("(an out of class initialization is required)"); - explained = 1; - } - init = NULL_TREE; - } - - DECL_INITIAL (decl) = init; DECL_IN_AGGR_P (decl) = 1; + if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE + && TYPE_DOMAIN (TREE_TYPE (decl)) == NULL_TREE) + SET_VAR_HAD_UNKNOWN_BOUND (decl); + cp_finish_decl (decl, init, init_const_expr_p, asmspec_tree, flags); } @@ -881,8 +902,13 @@ grokfield (const cp_declarator *declarator, } else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE) { - gcc_assert (error_operand_p (init) || integer_zerop (init)); - DECL_PURE_VIRTUAL_P (value) = 1; + if (integer_zerop (init)) + DECL_PURE_VIRTUAL_P (value) = 1; + else if (error_operand_p (init)) + ; /* An error has already been reported. */ + else + error ("invalid initializer for member function %qD", + value); } else { @@ -898,8 +924,7 @@ grokfield (const cp_declarator *declarator, { if (TREE_CODE (init) == CONSTRUCTOR) init = digest_init (TREE_TYPE (value), init); - else - init = integral_constant_value (init); + init = maybe_constant_init (init); if (init != error_mark_node && !TREE_CONSTANT (init)) { @@ -1026,7 +1051,10 @@ grokbitfield (const cp_declarator *declarator, if (width != error_mark_node) { - constant_expression_warning (width); + /* The width must be an integer type. */ + if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width))) + error ("width of bit-field %qD has non-integral type %qT", value, + TREE_TYPE (width)); DECL_INITIAL (value) = width; SET_DECL_C_BIT_FIELD (value); } @@ -1209,6 +1237,7 @@ cp_reconstruct_complex_type (tree type, tree bottom) { inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); outer = build_function_type (inner, TYPE_ARG_TYPES (type)); + outer = apply_memfn_quals (outer, type_memfn_quals (type)); } else if (TREE_CODE (type) == METHOD_TYPE) { @@ -1231,7 +1260,7 @@ cp_reconstruct_complex_type (tree type, tree bottom) if (TYPE_ATTRIBUTES (type)) outer = cp_build_type_attribute_variant (outer, TYPE_ATTRIBUTES (type)); - return cp_build_qualified_type (outer, TYPE_QUALS (type)); + return cp_build_qualified_type (outer, cp_type_quals (type)); } /* Like decl_attributes, but handle C++ complexity. */ @@ -1280,7 +1309,7 @@ build_anon_union_vars (tree type, tree object) for (field = TYPE_FIELDS (type); field != NULL_TREE; - field = TREE_CHAIN (field)) + field = DECL_CHAIN (field)) { tree decl; tree ref; @@ -1574,8 +1603,7 @@ comdat_linkage (tree decl) } } - if (DECL_LANG_SPECIFIC (decl)) - DECL_COMDAT (decl) = 1; + DECL_COMDAT (decl) = 1; } /* For win32 we also want to put explicit instantiations in @@ -1616,20 +1644,22 @@ maybe_make_one_only (tree decl) } } -/* Returns true iff DECL, a FUNCTION_DECL, has vague linkage. This - predicate will give the right answer during parsing of the function, - which other tests may not. */ +/* Returns true iff DECL, a FUNCTION_DECL or VAR_DECL, has vague linkage. + This predicate will give the right answer during parsing of the + function, which other tests may not. */ bool -vague_linkage_fn_p (tree fn) +vague_linkage_p (tree decl) { /* Unfortunately, import_export_decl has not always been called before the function is processed, so we cannot simply check DECL_COMDAT. */ - return (DECL_COMDAT (fn) - || ((DECL_DECLARED_INLINE_P (fn) - || DECL_TEMPLATE_INSTANTIATION (fn)) - && TREE_PUBLIC (fn))); + return (DECL_COMDAT (decl) + || (((TREE_CODE (decl) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (decl)) + || (DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_INSTANTIATION (decl))) + && TREE_PUBLIC (decl))); } /* Determine whether or not we want to specifically import or export CTYPE, @@ -1766,6 +1796,7 @@ maybe_emit_vtables (tree ctype) tree vtbl; tree primary_vtbl; int needed = 0; + struct varpool_node *current = NULL, *last = NULL, *first = NULL; /* If the vtables for this class have already been emitted there is nothing more to do. */ @@ -1783,7 +1814,7 @@ maybe_emit_vtables (tree ctype) determine_key_method (ctype); /* See if any of the vtables are needed. */ - for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl)) + for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl)) { import_export_decl (vtbl); if (DECL_NOT_REALLY_EXTERN (vtbl) && decl_needed_p (vtbl)) @@ -1802,7 +1833,7 @@ maybe_emit_vtables (tree ctype) /* The ABI requires that we emit all of the vtables if we emit any of them. */ - for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl)) + for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl)) { /* Mark entities references from the virtual table as used. */ mark_vtable_entries (vtbl); @@ -1823,8 +1854,20 @@ maybe_emit_vtables (tree ctype) actually marking the variable as written. */ if (flag_syntax_only) TREE_ASM_WRITTEN (vtbl) = 1; + else if (DECL_COMDAT (vtbl)) + { + current = varpool_node (vtbl); + if (last) + last->same_comdat_group = current; + last = current; + if (!first) + first = current; + } } + if (first != last) + last->same_comdat_group = first; + /* Since we're writing out the vtable here, also write the debug info. */ note_debug_info_needed (ctype); @@ -2187,7 +2230,7 @@ constrain_class_visibility (tree type) if (CLASSTYPE_VISIBILITY_SPECIFIED (type)) vis = VISIBILITY_INTERNAL; - for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t)) + for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t)) if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node) { tree ftype = strip_pointer_or_array_types (TREE_TYPE (t)); @@ -2555,7 +2598,9 @@ get_guard (tree decl) TREE_PUBLIC (guard) = TREE_PUBLIC (decl); TREE_STATIC (guard) = TREE_STATIC (decl); DECL_COMMON (guard) = DECL_COMMON (decl); - DECL_COMDAT_GROUP (guard) = DECL_COMDAT_GROUP (decl); + DECL_COMDAT (guard) = DECL_COMDAT (decl); + if (DECL_ONE_ONLY (decl)) + make_decl_one_only (guard, cxx_comdat_group (guard)); if (TREE_PUBLIC (decl)) DECL_WEAK (guard) = DECL_WEAK (decl); DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl); @@ -2667,8 +2712,8 @@ start_objects (int method_type, int initp) fndecl = build_lang_decl (FUNCTION_DECL, get_file_function_name (type), - build_function_type (void_type_node, - void_list_node)); + build_function_type_list (void_type_node, + NULL_TREE)); start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED); TREE_PUBLIC (current_function_decl) = 0; @@ -2760,7 +2805,6 @@ static splay_tree priority_info_map; static tree start_static_storage_duration_function (unsigned count) { - tree parm_types; tree type; tree body; char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32]; @@ -2769,11 +2813,9 @@ start_static_storage_duration_function (unsigned count) SSDF_IDENTIFIER_. */ sprintf (id, "%s_%u", SSDF_IDENTIFIER, count); - /* Create the parameters. */ - parm_types = void_list_node; - parm_types = tree_cons (NULL_TREE, integer_type_node, parm_types); - parm_types = tree_cons (NULL_TREE, integer_type_node, parm_types); - type = build_function_type (void_type_node, parm_types); + type = build_function_type_list (void_type_node, + integer_type_node, integer_type_node, + NULL_TREE); /* Create the FUNCTION_DECL itself. */ ssdf_decl = build_lang_decl (FUNCTION_DECL, @@ -2814,7 +2856,7 @@ start_static_storage_duration_function (unsigned count) DECL_CONTEXT (priority_decl) = ssdf_decl; TREE_USED (priority_decl) = 1; - TREE_CHAIN (initialize_p_decl) = priority_decl; + DECL_CHAIN (initialize_p_decl) = priority_decl; DECL_ARGUMENTS (ssdf_decl) = initialize_p_decl; /* Put the function in the global scope. */ @@ -2912,7 +2954,7 @@ fix_temporary_vars_context_r (tree *node, { tree var; - for (var = BIND_EXPR_VARS (*node); var; var = TREE_CHAIN (var)) + for (var = BIND_EXPR_VARS (*node); var; var = DECL_CHAIN (var)) if (TREE_CODE (var) == VAR_DECL && !DECL_NAME (var) && DECL_ARTIFICIAL (var) @@ -3219,7 +3261,6 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority, location_t *locus) { char function_key; - tree arguments; tree fndecl; tree body; size_t i; @@ -3247,22 +3288,23 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority, /* Call the static storage duration function with appropriate arguments. */ - for (i = 0; VEC_iterate (tree, ssdf_decls, i, fndecl); ++i) + FOR_EACH_VEC_ELT (tree, ssdf_decls, i, fndecl) { /* Calls to pure or const functions will expand to nothing. */ if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE))) { + tree call; + if (! body) body = start_objects (function_key, priority); - arguments = tree_cons (NULL_TREE, - build_int_cst (NULL_TREE, priority), - NULL_TREE); - arguments = tree_cons (NULL_TREE, - build_int_cst (NULL_TREE, constructor_p), - arguments); - finish_expr_stmt (cp_build_function_call (fndecl, arguments, - tf_warning_or_error)); + call = cp_build_function_call_nary (fndecl, tf_warning_or_error, + build_int_cst (NULL_TREE, + constructor_p), + build_int_cst (NULL_TREE, + priority), + NULL_TREE); + finish_expr_stmt (call); } } @@ -3314,19 +3356,9 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED) cgraph_mark_address_taken_node (cgraph_node (BASELINK_FUNCTIONS (t))); break; case VAR_DECL: - if (DECL_VTABLE_OR_VTT_P (t)) - { - /* The ABI requires that all virtual tables be emitted - whenever one of them is. */ - tree vtbl; - for (vtbl = CLASSTYPE_VTABLES (DECL_CONTEXT (t)); - vtbl; - vtbl = TREE_CHAIN (vtbl)) - mark_decl_referenced (vtbl); - } - else if (DECL_CONTEXT (t) - && flag_use_repository - && TREE_CODE (DECL_CONTEXT (t)) == FUNCTION_DECL) + if (DECL_CONTEXT (t) + && flag_use_repository + && TREE_CODE (DECL_CONTEXT (t)) == FUNCTION_DECL) /* If we need a static variable in a function, then we need the containing function. */ mark_decl_referenced (DECL_CONTEXT (t)); @@ -3415,6 +3447,69 @@ build_java_method_aliases (struct pointer_set_t *candidates) } } +/* Return C++ property of T, based on given operation OP. */ + +static int +cpp_check (tree t, cpp_operation op) +{ + switch (op) + { + case IS_ABSTRACT: + return DECL_PURE_VIRTUAL_P (t); + case IS_CONSTRUCTOR: + return DECL_CONSTRUCTOR_P (t); + case IS_DESTRUCTOR: + return DECL_DESTRUCTOR_P (t); + case IS_COPY_CONSTRUCTOR: + return DECL_COPY_CONSTRUCTOR_P (t); + case IS_TEMPLATE: + return TREE_CODE (t) == TEMPLATE_DECL; + default: + return 0; + } +} + +/* Collect source file references recursively, starting from NAMESPC. */ + +static void +collect_source_refs (tree namespc) +{ + tree t; + + if (!namespc) + return; + + /* Iterate over names in this name space. */ + for (t = NAMESPACE_LEVEL (namespc)->names; t; t = TREE_CHAIN (t)) + if (!DECL_IS_BUILTIN (t) ) + collect_source_ref (DECL_SOURCE_FILE (t)); + + /* Dump siblings, if any */ + collect_source_refs (TREE_CHAIN (namespc)); + + /* Dump children, if any */ + collect_source_refs (NAMESPACE_LEVEL (namespc)->namespaces); +} + +/* Collect decls relevant to SOURCE_FILE from all namespaces recursively, + starting from NAMESPC. */ + +static void +collect_ada_namespace (tree namespc, const char *source_file) +{ + if (!namespc) + return; + + /* Collect decls from this namespace */ + collect_ada_nodes (NAMESPACE_LEVEL (namespc)->names, source_file); + + /* Collect siblings, if any */ + collect_ada_namespace (TREE_CHAIN (namespc), source_file); + + /* Collect children, if any */ + collect_ada_namespace (NAMESPACE_LEVEL (namespc)->namespaces, source_file); +} + /* Returns true iff there is a definition available for variable or function DECL. */ @@ -3430,6 +3525,60 @@ decl_defined_p (tree decl) } } +/* Nonzero for a VAR_DECL whose value can be used in a constant expression. + + [expr.const] + + An integral constant-expression can only involve ... const + variables of integral or enumeration types initialized with + constant expressions ... + + C++0x also allows constexpr variables and temporaries initialized + with constant expressions. We handle the former here, but the latter + are just folded away in cxx_eval_constant_expression. + + The standard does not require that the expression be non-volatile. + G++ implements the proposed correction in DR 457. */ + +bool +decl_constant_var_p (tree decl) +{ + bool ret; + tree type = TREE_TYPE (decl); + if (TREE_CODE (decl) != VAR_DECL) + return false; + if (DECL_DECLARED_CONSTEXPR_P (decl)) + ret = true; + else if (CP_TYPE_CONST_NON_VOLATILE_P (type) + && INTEGRAL_OR_ENUMERATION_TYPE_P (type)) + { + /* We don't know if a template static data member is initialized with + a constant expression until we instantiate its initializer. */ + mark_used (decl); + ret = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl); + } + else + ret = false; + + gcc_assert (!ret || DECL_INITIAL (decl)); + return ret; +} + +/* Returns true if DECL could be a symbolic constant variable, depending on + its initializer. */ + +bool +decl_maybe_constant_var_p (tree decl) +{ + tree type = TREE_TYPE (decl); + if (TREE_CODE (decl) != VAR_DECL) + return false; + if (DECL_DECLARED_CONSTEXPR_P (decl)) + return true; + return (CP_TYPE_CONST_NON_VOLATILE_P (type) + && INTEGRAL_OR_ENUMERATION_TYPE_P (type)); +} + /* Complain that DECL uses a type with no linkage but is never defined. */ static void @@ -3449,6 +3598,14 @@ no_linkage_error (tree decl) "is used but never defined", decl, t); } +/* Collect declarations from all namespaces relevant to SOURCE_FILE. */ + +static void +collect_all_refs (const char *source_file) +{ + collect_ada_namespace (global_namespace, source_file); +} + /* This routine is called at the end of compilation. Its job is to create all the code needed to initialize and destroy the global aggregates. We do the destruction @@ -3470,12 +3627,24 @@ cp_write_global_declarations (void) at_eof = 1; /* Bad parse errors. Just forget about it. */ - if (! global_bindings_p () || current_class_type || decl_namespace_list) + if (! global_bindings_p () || current_class_type + || !VEC_empty (tree,decl_namespace_list)) return; if (pch_file) c_common_write_pch (); + /* Handle -fdump-ada-spec[-slim] */ + if (dump_enabled_p (TDI_ada)) + { + if (get_dump_file_info (TDI_ada)->flags & TDF_SLIM) + collect_source_ref (main_input_filename); + else + collect_source_refs (global_namespace); + + dump_ada_specs (collect_all_refs, cpp_check); + } + /* FIXME - huh? was input_line -= 1;*/ /* We now have to write out all the stuff we put off writing out. @@ -3615,7 +3784,7 @@ cp_write_global_declarations (void) /* Go through the set of inline functions whose bodies have not been emitted yet. If out-of-line copies of these functions are required, emit them. */ - for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i) + FOR_EACH_VEC_ELT (tree, deferred_fns, i, decl) { /* Does it need synthesizing? */ if (DECL_DEFAULTED_FN (decl) && ! DECL_INITIAL (decl) @@ -3658,7 +3827,36 @@ cp_write_global_declarations (void) if (DECL_NOT_REALLY_EXTERN (decl) && DECL_INITIAL (decl) && decl_needed_p (decl)) - DECL_EXTERNAL (decl) = 0; + { + struct cgraph_node *node = cgraph_get_node (decl), *alias, *next; + + DECL_EXTERNAL (decl) = 0; + /* If we mark !DECL_EXTERNAL one of the same body aliases, + we need to mark all of them that way. */ + if (node && node->same_body) + { + DECL_EXTERNAL (node->decl) = 0; + for (alias = node->same_body; alias; alias = alias->next) + DECL_EXTERNAL (alias->decl) = 0; + } + /* If we mark !DECL_EXTERNAL one of the symbols in some comdat + group, we need to mark all symbols in the same comdat group + that way. */ + if (node->same_comdat_group) + for (next = node->same_comdat_group; + next != node; + next = next->same_comdat_group) + { + DECL_EXTERNAL (next->decl) = 0; + if (next->same_body) + { + for (alias = next->same_body; + alias; + alias = alias->next) + DECL_EXTERNAL (alias->decl) = 0; + } + } + } /* If we're going to need to write this function out, and there's already a body for it, create RTL for it now. @@ -3688,7 +3886,7 @@ cp_write_global_declarations (void) reconsider = true; /* Static data members are just like namespace-scope globals. */ - for (i = 0; VEC_iterate (tree, pending_statics, i, decl); ++i) + FOR_EACH_VEC_ELT (tree, pending_statics, i, decl) { if (var_finalized_p (decl) || DECL_REALLY_EXTERN (decl) /* Don't write it out if we haven't seen a definition. */ @@ -3710,7 +3908,7 @@ cp_write_global_declarations (void) while (reconsider); /* All used inline functions must have a definition at this point. */ - for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i) + FOR_EACH_VEC_ELT (tree, deferred_fns, i, decl) { if (/* Check online inline functions that were actually used. */ DECL_ODR_USED (decl) && DECL_DECLARED_INLINE_P (decl) @@ -3732,10 +3930,18 @@ cp_write_global_declarations (void) } /* So must decls that use a type with no linkage. */ - for (i = 0; VEC_iterate (tree, no_linkage_decls, i, decl); ++i) + FOR_EACH_VEC_ELT (tree, no_linkage_decls, i, decl) if (!decl_defined_p (decl)) no_linkage_error (decl); + /* Then, do the Objective-C stuff. This is where all the + Objective-C module stuff gets generated (symtab, + class/protocol/selector lists etc). This must be done after C++ + templates, destructors etc. so that selectors used in C++ + templates are properly allocated. */ + if (c_dialect_objc ()) + objc_write_global_declarations (); + /* We give C linkage to static constructors and destructors. */ push_lang_context (lang_name_c); @@ -3778,6 +3984,8 @@ cp_write_global_declarations (void) VEC_length (tree, pending_statics)); } + perform_deferred_noexcept_checks (); + /* Generate hidden aliases for Java. */ if (candidates) { @@ -3847,7 +4055,7 @@ build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args) make_args_non_dependent (*args); object = build_non_dependent_expr (object); if (TREE_CODE (fn) == DOTSTAR_EXPR) - object = cp_build_unary_op (ADDR_EXPR, object, 0, tf_warning_or_error); + object = cp_build_addr_expr (object, tf_warning_or_error); VEC_safe_insert (tree, gc, *args, 0, object); /* Now that the arguments are done, transform FN. */ fn = build_non_dependent_expr (fn); @@ -3861,8 +4069,7 @@ build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args) void B::g() { (this->*p)(); } */ if (TREE_CODE (fn) == OFFSET_REF) { - tree object_addr = cp_build_unary_op (ADDR_EXPR, object, 0, - tf_warning_or_error); + tree object_addr = cp_build_addr_expr (object, tf_warning_or_error); fn = TREE_OPERAND (fn, 1); fn = get_member_function_from_ptrfunc (&object_addr, fn); VEC_safe_insert (tree, gc, *args, 0, object_addr); @@ -3920,8 +4127,6 @@ possibly_inlined_p (tree decl) void mark_used (tree decl) { - HOST_WIDE_INT saved_processing_template_decl = 0; - /* If DECL is a BASELINK for a single function, then treat it just like the DECL for the function. Otherwise, if the BASELINK is for an overloaded function, we don't know which function was @@ -3942,13 +4147,23 @@ mark_used (tree decl) if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DELETED_FN (decl)) { - error ("deleted function %q+D", decl); - error ("used here"); + if (DECL_ARTIFICIAL (decl)) + { + if (DECL_OVERLOADED_OPERATOR_P (decl) == TYPE_EXPR + && LAMBDA_TYPE_P (DECL_CONTEXT (decl))) + { + /* We mark a lambda conversion op as deleted if we can't + generate it properly; see maybe_add_lambda_conv_op. */ + sorry ("converting lambda which uses %<...%> to " + "function pointer"); + return; + } + } + error ("use of deleted function %qD", decl); + if (!maybe_explain_implicit_delete (decl)) + error_at (DECL_SOURCE_LOCATION (decl), "declared here"); return; } - /* If we don't need a value, then we don't need to synthesize DECL. */ - if (cp_unevaluated_operand != 0) - return; /* We can only check DECL_ODR_USED on variables or functions with DECL_LANG_SPECIFIC set, and these are also the only decls that we @@ -3972,31 +4187,39 @@ mark_used (tree decl) return; } - /* Normally, we can wait until instantiation-time to synthesize - DECL. However, if DECL is a static data member initialized with - a constant, we need the value right now because a reference to - such a data member is not value-dependent. */ - if (TREE_CODE (decl) == VAR_DECL - && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) - && DECL_CLASS_SCOPE_P (decl)) - { - /* Don't try to instantiate members of dependent types. We - cannot just use dependent_type_p here because this function - may be called from fold_non_dependent_expr, and then we may - see dependent types, even though processing_template_decl - will not be set. */ - if (CLASSTYPE_TEMPLATE_INFO ((DECL_CONTEXT (decl))) - && uses_template_parms (CLASSTYPE_TI_ARGS (DECL_CONTEXT (decl)))) - return; - /* Pretend that we are not in a template, even if we are, so - that the static data member initializer will be processed. */ - saved_processing_template_decl = processing_template_decl; - processing_template_decl = 0; + /* Normally, we can wait until instantiation-time to synthesize DECL. + However, if DECL is a static data member initialized with a constant + or a constexpr function, we need it right now because a reference to + such a data member or a call to such function is not value-dependent. */ + if ((decl_maybe_constant_var_p (decl) + || (TREE_CODE (decl) == FUNCTION_DECL + && DECL_DECLARED_CONSTEXPR_P (decl))) + && !DECL_INITIAL (decl) + && DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_INSTANTIATION (decl)) + { + /* Instantiating a function will result in garbage collection. We + must treat this situation as if we were within the body of a + function so as to avoid collecting live data only referenced from + the stack (such as overload resolution candidates). */ + ++function_depth; + instantiate_decl (decl, /*defer_ok=*/false, + /*expl_inst_class_mem_p=*/false); + --function_depth; } + /* If we don't need a value, then we don't need to synthesize DECL. */ + if (cp_unevaluated_operand != 0) + return; + if (processing_template_decl) return; + /* Check this too in case we're within fold_non_dependent_expr. */ + if (DECL_TEMPLATE_INFO (decl) + && uses_template_parms (DECL_TI_ARGS (decl))) + return; + DECL_ODR_USED (decl) = 1; if (DECL_CLONED_FUNCTION_P (decl)) DECL_ODR_USED (DECL_CLONED_FUNCTION (decl)) = 1; @@ -4066,8 +4289,6 @@ mark_used (tree decl) need. Therefore, we always try to defer instantiation. */ instantiate_decl (decl, /*defer_ok=*/true, /*expl_inst_class_mem_p=*/false); - - processing_template_decl = saved_processing_template_decl; } #include "gt-cp-decl2.h"