X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl2.c;h=97b3ee0f3f25adf6e607c04ba35d402b49f258d1;hb=1e307880e3f8c596704fae458a8378068b807d5c;hp=a1664b81bcd94a44d62d625a7f4aed1b29f30ecc;hpb=2970ab3d17c41b33da12f9d80a5f83990d475645;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a1664b81bcd..97b3ee0f3f2 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1,13 +1,13 @@ /* Process declarations and variables for C++ compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, @@ -16,9 +16,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ /* Process declarations and symbol lookup for C++ front end. @@ -136,6 +135,12 @@ cp_build_parm_decl (tree name, tree type) sees templates. */ if (!processing_template_decl) DECL_ARG_TYPE (parm) = type_passed_as (type); + + /* If the type is a pack expansion, then we have a function + parameter pack. */ + if (type && TREE_CODE (type) == TYPE_PACK_EXPANSION) + FUNCTION_PARAMETER_PACK_P (parm) = 1; + return parm; } @@ -535,8 +540,8 @@ check_java_method (tree method) TEMPLATE_DECL, it can be NULL since the parameters can be extracted from the declaration. If the function is not a function template, it must be NULL. - It returns the original declaration for the function, or NULL_TREE - if no declaration was found (and an error was emitted). */ + It returns the original declaration for the function, NULL_TREE if + no declaration was found, error_mark_node if an error was emitted. */ tree check_classfn (tree ctype, tree function, tree template_parms) @@ -672,16 +677,9 @@ check_classfn (tree ctype, tree function, tree template_parms) error ("no %q#D member function declared in class %qT", function, ctype); - /* If we did not find the method in the class, add it to avoid - spurious errors (unless the CTYPE is not yet defined, in which - case we'll only confuse ourselves when the function is declared - properly within the class. */ - if (COMPLETE_TYPE_P (ctype)) - add_method (ctype, function, NULL_TREE); - if (pushed_scope) pop_scope (pushed_scope); - return NULL_TREE; + return error_mark_node; } /* DECL is a function with vague linkage. Remember it so that at the @@ -802,16 +800,7 @@ grokfield (const cp_declarator *declarator, value = push_template_decl (value); if (attrlist) - { - /* Avoid storing attributes in template parameters: - tsubst is not ready to handle them. */ - tree type = TREE_TYPE (value); - if (TREE_CODE (type) == TEMPLATE_TYPE_PARM - || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) - sorry ("applying attributes to template parameters is not implemented"); - else - cplus_decl_attributes (&value, attrlist, 0); - } + cplus_decl_attributes (&value, attrlist, 0); return value; } @@ -987,13 +976,127 @@ grokbitfield (const cp_declarator *declarator, } +/* Returns true iff ATTR is an attribute which needs to be applied at + instantiation time rather than template definition time. */ + +static bool +is_late_template_attribute (tree attr, tree decl) +{ + tree name = TREE_PURPOSE (attr); + tree args = TREE_VALUE (attr); + const struct attribute_spec *spec = lookup_attribute_spec (name); + + if (!spec) + /* Unknown attribute. */ + return false; + + if (is_attribute_p ("aligned", name) + && args + && value_dependent_expression_p (TREE_VALUE (args))) + /* Can't apply this until we know the desired alignment. */ + return true; + else if (TREE_CODE (decl) == TYPE_DECL || spec->type_required) + { + tree type = TYPE_P (decl) ? decl : TREE_TYPE (decl); + + /* We can't apply any attributes to a completely unknown type until + instantiation time. */ + enum tree_code code = TREE_CODE (type); + if (code == TEMPLATE_TYPE_PARM + || code == BOUND_TEMPLATE_TEMPLATE_PARM + || code == TYPENAME_TYPE) + return true; + else + return false; + } + else + return false; +} + +/* ATTR_P is a list of attributes. Remove any attributes which need to be + applied at instantiation time and return them. If IS_DEPENDENT is true, + the declaration itself is dependent, so all attributes should be applied + at instantiation time. */ + +static tree +splice_template_attributes (tree *attr_p, tree decl) +{ + tree *p = attr_p; + tree late_attrs = NULL_TREE; + tree *q = &late_attrs; + + if (!p) + return NULL_TREE; + + for (; *p; ) + { + if (is_late_template_attribute (*p, decl)) + { + ATTR_IS_DEPENDENT (*p) = 1; + *q = *p; + *p = TREE_CHAIN (*p); + q = &TREE_CHAIN (*q); + *q = NULL_TREE; + } + else + p = &TREE_CHAIN (*p); + } + + return late_attrs; +} + +/* Remove any late attributes from the list in ATTR_P and attach them to + DECL_P. */ + +static void +save_template_attributes (tree *attr_p, tree *decl_p) +{ + tree late_attrs = splice_template_attributes (attr_p, *decl_p); + tree *q; + + if (!late_attrs) + return; + + /* Give this type a name so we know to look it up again at instantiation + time. */ + if (TREE_CODE (*decl_p) == TYPE_DECL + && DECL_ORIGINAL_TYPE (*decl_p) == NULL_TREE) + { + tree oldt = TREE_TYPE (*decl_p); + tree newt = build_variant_type_copy (oldt); + DECL_ORIGINAL_TYPE (*decl_p) = oldt; + TREE_TYPE (*decl_p) = newt; + TYPE_NAME (newt) = *decl_p; + TREE_USED (newt) = TREE_USED (*decl_p); + } + + if (DECL_P (*decl_p)) + q = &DECL_ATTRIBUTES (*decl_p); + else + q = &TYPE_ATTRIBUTES (*decl_p); + + if (*q) + q = &TREE_CHAIN (tree_last (*q)); + *q = late_attrs; +} + +/* Like decl_attributes, but handle C++ complexity. */ + void cplus_decl_attributes (tree *decl, tree attributes, int flags) { if (*decl == NULL_TREE || *decl == void_type_node - || *decl == error_mark_node) + || *decl == error_mark_node + || attributes == NULL_TREE) return; + if (processing_template_decl) + { + save_template_attributes (&attributes, decl); + if (attributes == NULL_TREE) + return; + } + if (TREE_CODE (*decl) == TEMPLATE_DECL) decl = &DECL_TEMPLATE_RESULT (*decl); @@ -1051,6 +1154,7 @@ build_anon_union_vars (tree type, tree object) tree base; decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field)); + DECL_ANON_UNION_VAR_P (decl) = 1; base = get_base_address (object); TREE_PUBLIC (decl) = TREE_PUBLIC (base); @@ -1147,15 +1251,33 @@ coerce_new_type (tree type) error ("% must return type %qT", ptr_type_node); } - if (!args || args == void_list_node - || !same_type_p (TREE_VALUE (args), size_type_node)) + if (args && args != void_list_node) { - e = 2; - if (args && args != void_list_node) - args = TREE_CHAIN (args); - pedwarn ("% takes type % (%qT) " - "as first parameter", size_type_node); + if (TREE_PURPOSE (args)) + { + /* [basic.stc.dynamic.allocation] + + The first parameter shall not have an associated default + argument. */ + error ("the first parameter of % cannot " + "have a default argument"); + /* Throw away the default argument. */ + TREE_PURPOSE (args) = NULL_TREE; + } + + if (!same_type_p (TREE_VALUE (args), size_type_node)) + { + e = 2; + args = TREE_CHAIN (args); + } } + else + e = 2; + + if (e == 2) + pedwarn ("% takes type % (%qT) " + "as first parameter", size_type_node); + switch (e) { case 2: @@ -1210,6 +1332,9 @@ coerce_delete_type (tree type) return type; } +/* DECL is a VAR_DECL for a vtable: walk through the entries in the vtable + and mark them as needed. */ + static void mark_vtable_entries (tree decl) { @@ -1562,7 +1687,7 @@ static int type_visibility (tree type) { int vis = VISIBILITY_DEFAULT; - walk_tree_without_duplicates (&type, min_vis_r, &vis); + cp_walk_tree_without_duplicates (&type, min_vis_r, &vis); return vis; } @@ -1579,6 +1704,7 @@ constrain_visibility (tree decl, int visibility) if (!DECL_EXTERN_C_P (decl)) { TREE_PUBLIC (decl) = 0; + DECL_ONE_ONLY (decl) = 0; DECL_INTERFACE_KNOWN (decl) = 1; if (DECL_LANG_SPECIFIC (decl)) DECL_NOT_REALLY_EXTERN (decl) = 1; @@ -1677,25 +1803,10 @@ determine_visibility (tree decl) else use_template = 0; - /* Anything that is exported must have default visibility. */ - if (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && lookup_attribute ("dllexport", - TREE_CODE (decl) == TYPE_DECL - ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) - : DECL_ATTRIBUTES (decl))) - { - DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; - DECL_VISIBILITY_SPECIFIED (decl) = 1; - } - /* If DECL is a member of a class, visibility specifiers on the class can influence the visibility of the DECL. */ if (DECL_CLASS_SCOPE_P (decl)) class_type = DECL_CONTEXT (decl); - else if (TREE_CODE (decl) == VAR_DECL - && DECL_TINFO_P (decl) - && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl)))) - class_type = TREE_TYPE (DECL_NAME (decl)); else { /* Not a class member. */ @@ -1724,6 +1835,19 @@ determine_visibility (tree decl) but have no TEMPLATE_INFO, so don't try to check it. */ use_template = 0; } + else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl) + && flag_visibility_ms_compat) + { + /* Under -fvisibility-ms-compat, types are visible by default, + even though their contents aren't. */ + tree underlying_type = TREE_TYPE (DECL_NAME (decl)); + int underlying_vis = type_visibility (underlying_type); + if (underlying_vis == VISIBILITY_ANON + || CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type)) + constrain_visibility (decl, underlying_vis); + else + DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; + } else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl)) { /* tinfo visibility is based on the type it's for. */ @@ -1781,7 +1905,8 @@ determine_visibility (tree decl) { /* Propagate anonymity from type to decl. */ int tvis = type_visibility (TREE_TYPE (decl)); - if (tvis == VISIBILITY_ANON) + if (tvis == VISIBILITY_ANON + || ! DECL_VISIBILITY_SPECIFIED (decl)) constrain_visibility (decl, tvis); } } @@ -1792,18 +1917,20 @@ determine_visibility (tree decl) static void determine_visibility_from_class (tree decl, tree class_type) { + if (DECL_VISIBILITY_SPECIFIED (decl)) + return; + if (visibility_options.inlines_hidden /* Don't do this for inline templates; specializations might not be inline, and we don't want them to inherit the hidden visibility. We'll set it here for all inline instantiations. */ && !processing_template_decl - && ! DECL_VISIBILITY_SPECIFIED (decl) && TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) && (! DECL_LANG_SPECIFIC (decl) || ! DECL_EXPLICIT_INSTANTIATION (decl))) DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; - else if (!DECL_VISIBILITY_SPECIFIED (decl)) + else { /* Default to the class visibility. */ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type); @@ -1822,7 +1949,6 @@ determine_visibility_from_class (tree decl, tree class_type) && !DECL_CONSTRUCTION_VTABLE_P (decl))) && TREE_PUBLIC (decl) && !DECL_REALLY_EXTERN (decl) - && !DECL_VISIBILITY_SPECIFIED (decl) && !CLASSTYPE_VISIBILITY_SPECIFIED (class_type)) targetm.cxx.determine_class_data_visibility (decl); } @@ -1850,13 +1976,16 @@ constrain_class_visibility (tree type) for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t)) if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node) { - tree ftype = strip_array_types (TREE_TYPE (t)); + tree ftype = strip_pointer_or_array_types (TREE_TYPE (t)); int subvis = type_visibility (ftype); if (subvis == VISIBILITY_ANON) - warning (0, "\ + { + if (!in_main_input_context ()) + warning (0, "\ %qT has a field %qD whose type uses the anonymous namespace", - type, t); + type, t); + } else if (IS_AGGR_TYPE (ftype) && vis < VISIBILITY_HIDDEN && subvis >= VISIBILITY_HIDDEN) @@ -1871,9 +2000,12 @@ constrain_class_visibility (tree type) int subvis = type_visibility (TREE_TYPE (t)); if (subvis == VISIBILITY_ANON) - warning (0, "\ + { + if (!in_main_input_context()) + warning (0, "\ %qT has a base %qT whose type uses the anonymous namespace", - type, TREE_TYPE (t)); + type, TREE_TYPE (t)); + } else if (vis < VISIBILITY_HIDDEN && subvis >= VISIBILITY_HIDDEN) warning (OPT_Wattributes, "\ @@ -2098,7 +2230,8 @@ import_export_decl (tree decl) { /* DECL is an implicit instantiation of a function or static data member. */ - if (flag_implicit_templates + if ((flag_implicit_templates + && !flag_use_repository) || (flag_implicit_inline_templates && TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))) @@ -2176,10 +2309,7 @@ build_cleanup (tree decl) if (TREE_CODE (type) == ARRAY_TYPE) temp = decl; else - { - cxx_mark_addressable (decl); - temp = build1 (ADDR_EXPR, build_pointer_type (type), decl); - } + temp = build_address (decl); temp = build_delete (TREE_TYPE (temp), temp, sfk_complete_destructor, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); @@ -2213,6 +2343,8 @@ get_guard (tree decl) DECL_ONE_ONLY (guard) = DECL_ONE_ONLY (decl); if (TREE_PUBLIC (decl)) DECL_WEAK (guard) = DECL_WEAK (decl); + DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl); + DECL_VISIBILITY_SPECIFIED (guard) = DECL_VISIBILITY_SPECIFIED (decl); DECL_ARTIFICIAL (guard) = 1; DECL_IGNORED_P (guard) = 1; @@ -2319,9 +2451,11 @@ start_objects (int method_type, int initp) void_list_node)); start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED); - /* It can be a static function as long as collect2 does not have - to scan the object file to find its ctor/dtor routine. */ - TREE_PUBLIC (current_function_decl) = ! targetm.have_ctors_dtors; + TREE_PUBLIC (current_function_decl) = 0; + + /* Mark as artificial because it's not explicitly in the user's + source code. */ + DECL_ARTIFICIAL (current_function_decl) = 1; /* Mark this declaration as used to avoid spurious warnings. */ TREE_USED (current_function_decl) = 1; @@ -2349,23 +2483,19 @@ finish_objects (int method_type, int initp, tree body) /* Finish up. */ finish_compound_stmt (body); fn = finish_function (0); - expand_or_defer_fn (fn); - /* When only doing semantic analysis, and no RTL generation, we - can't call functions that directly emit assembly code; there is - no assembly file in which to put the code. */ - if (flag_syntax_only) - return; - - if (targetm.have_ctors_dtors) + if (method_type == 'I') { - rtx fnsym = XEXP (DECL_RTL (fn), 0); - cgraph_mark_needed_node (cgraph_node (fn)); - if (method_type == 'I') - (* targetm.asm_out.constructor) (fnsym, initp); - else - (* targetm.asm_out.destructor) (fnsym, initp); + DECL_STATIC_CONSTRUCTOR (fn) = 1; + decl_init_priority_insert (fn, initp); + } + else + { + DECL_STATIC_DESTRUCTOR (fn) = 1; + decl_fini_priority_insert (fn, initp); } + + expand_or_defer_fn (fn); } /* The names of the parameters to the function created to handle @@ -2898,8 +3028,7 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data) Here we must deal with member pointers. */ tree -cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, - tree from ATTRIBUTE_UNUSED) +cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED) { tree t = *tp; @@ -3289,8 +3418,6 @@ cp_write_global_declarations (void) if (priority_info_map) splay_tree_delete (priority_info_map); - c_build_cdtor_fns (); - /* Generate any missing aliases. */ maybe_apply_pending_pragma_weaks (); @@ -3373,9 +3500,9 @@ build_offset_ref_call_from_tree (tree fn, tree args) parameter. That must be done before the FN is transformed because we depend on the form of FN. */ args = build_non_dependent_args (args); + object = build_non_dependent_expr (object); if (TREE_CODE (fn) == DOTSTAR_EXPR) object = build_unary_op (ADDR_EXPR, object, 0); - object = build_non_dependent_expr (object); args = tree_cons (NULL_TREE, object, args); /* Now that the arguments are done, transform FN. */ fn = build_non_dependent_expr (fn);