X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcp%2Fsearch.c;h=370ddf636c33a31b2de59843f81ad373a6df41b2;hp=21d1b7762465cc44b0ffa4b9bbe38599abb67506;hb=494f3f05703f498e674b3c7c229315f4a803e0a8;hpb=074ab442f459e8d6fa5cb8f36e98b20468f7a35a diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 21d1b776246..370ddf636c3 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1,14 +1,15 @@ /* Breadth-first and depth-first routines for searching multiple-inheritance lattice for GNU C++. Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. Contributed 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, @@ -17,9 +18,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 +. */ /* High-level class interface. */ @@ -29,11 +29,11 @@ Boston, MA 02110-1301, USA. */ #include "tm.h" #include "tree.h" #include "cp-tree.h" -#include "obstack.h" +#include "intl.h" #include "flags.h" -#include "rtl.h" #include "output.h" #include "toplev.h" +#include "target.h" static int is_subobject_of_p (tree, tree); static tree dfs_lookup_base (tree, void *); @@ -62,7 +62,6 @@ static tree dfs_access_in_type (tree, void *); static access_kind access_in_type (tree, tree); static int protected_accessible_p (tree, tree, tree); static int friend_accessible_p (tree, tree, tree); -static int template_self_reference_p (tree, tree); static tree dfs_get_pure_virtuals (tree, void *); @@ -171,7 +170,7 @@ accessible_base_p (tree t, tree base, bool consider_local_p) public typedef created in the scope of every class. */ decl = TYPE_FIELDS (base); while (!DECL_SELF_REFERENCE_P (decl)) - decl = TREE_CHAIN (decl); + decl = DECL_CHAIN (decl); while (ANON_AGGR_TYPE_P (t)) t = TYPE_CONTEXT (t); return accessible_p (t, decl, consider_local_p); @@ -213,9 +212,11 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr) t_binfo = TYPE_BINFO (t); } - base = complete_type (TYPE_MAIN_VARIANT (base)); + base = TYPE_MAIN_VARIANT (base); - if (t_binfo) + /* If BASE is incomplete, it can't be a base of T--and instantiating it + might cause an error. */ + if (t_binfo && CLASS_TYPE_P (base) && COMPLETE_OR_OPEN_TYPE_P (base)) { struct lookup_base_data_s data; @@ -394,12 +395,10 @@ lookup_field_1 (tree type, tree name, bool want_type) The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME. */ return NULL_TREE; - if (TYPE_NAME (type) - && DECL_LANG_SPECIFIC (TYPE_NAME (type)) - && DECL_SORTED_FIELDS (TYPE_NAME (type))) + if (CLASSTYPE_SORTED_FIELDS (type)) { - tree *fields = &DECL_SORTED_FIELDS (TYPE_NAME (type))->elts[0]; - int lo = 0, hi = DECL_SORTED_FIELDS (TYPE_NAME (type))->len; + tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0]; + int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len; int i; while (lo < hi) @@ -448,7 +447,7 @@ lookup_field_1 (tree type, tree name, bool want_type) #ifdef GATHER_STATISTICS n_calls_lookup_field_1++; #endif /* GATHER_STATISTICS */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { #ifdef GATHER_STATISTICS n_fields_searched++; @@ -720,20 +719,13 @@ protected_accessible_p (tree decl, tree derived, tree binfo) m as a member of N is protected, and the reference occurs in a member or friend of class N, or in a member or friend of a - class P derived from N, where m as a member of P is private or - protected. - - Here DERIVED is a possible P and DECL is m. accessible_p will - iterate over various values of N, but the access to m in DERIVED - does not change. + class P derived from N, where m as a member of P is public, private + or protected. - Note that I believe that the passage above is wrong, and should read - "...is private or protected or public"; otherwise you get bizarre results - whereby a public using-decl can prevent you from accessing a protected - member of a base. (jason 2000/02/28) */ + Here DERIVED is a possible P, DECL is m and BINFO_TYPE (binfo) is N. */ - /* If DERIVED isn't derived from m's class, then it can't be a P. */ - if (!DERIVED_FROM_P (context_for_name_lookup (decl), derived)) + /* If DERIVED isn't derived from N, then it can't be a P. */ + if (!DERIVED_FROM_P (BINFO_TYPE (binfo), derived)) return 0; access = access_in_type (derived, decl); @@ -792,8 +784,8 @@ friend_accessible_p (tree scope, tree decl, tree binfo) if (protected_accessible_p (decl, TREE_VALUE (t), binfo)) return 1; - /* Nested classes are implicitly friends of their enclosing types, as - per core issue 45 (this is a change from the standard). */ + /* Nested classes have the same access as their enclosing types, as + per DR 45 (this is a change from the standard). */ if (TYPE_P (scope)) for (t = TYPE_CONTEXT (scope); t && TYPE_P (t); t = TYPE_CONTEXT (t)) if (protected_accessible_p (decl, t, binfo)) @@ -960,24 +952,6 @@ struct lookup_field_info { const char *errstr; }; -/* Within the scope of a template class, you can refer to the to the - current specialization with the name of the template itself. For - example: - - template struct S { S* sp; } - - Returns nonzero if DECL is such a declaration in a class TYPE. */ - -static int -template_self_reference_p (tree type, tree decl) -{ - return (CLASSTYPE_USE_TEMPLATE (type) - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)) - && TREE_CODE (decl) == TYPE_DECL - && DECL_ARTIFICIAL (decl) - && DECL_NAME (decl) == constructor_name (type)); -} - /* Nonzero for a class member means that it is shared between all objects of that class. @@ -996,6 +970,7 @@ shared_member_p (tree t) return 1; if (is_overloaded_fn (t)) { + t = get_fns (t); for (; t; t = OVL_NEXT (t)) { tree fn = OVL_CURRENT (t); @@ -1097,11 +1072,6 @@ lookup_field_r (tree binfo, void *data) } } - /* You must name a template base class with a template-id. */ - if (!same_type_p (type, lfi->type) - && template_self_reference_p (type, nval)) - goto done; - /* If the lookup already found a match, and the new value doesn't hide the old one, we might have an ambiguity. */ if (lfi->rval_binfo @@ -1130,7 +1100,7 @@ lookup_field_r (tree binfo, void *data) /* Add the new value. */ lfi->ambiguous = tree_cons (NULL_TREE, nval, lfi->ambiguous); TREE_TYPE (lfi->ambiguous) = error_mark_node; - lfi->errstr = "request for member %qD is ambiguous"; + lfi->errstr = G_("request for member %qD is ambiguous"); } } else @@ -1200,6 +1170,9 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) const char *errstr = 0; + if (name == error_mark_node) + return NULL_TREE; + gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); if (TREE_CODE (xbasetype) == TREE_BINFO) @@ -1209,7 +1182,8 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) } else { - gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype))); + if (!RECORD_OR_UNION_CODE_P (TREE_CODE (xbasetype))) + return NULL_TREE; type = xbasetype; xbasetype = NULL_TREE; } @@ -1252,9 +1226,27 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) /* [class.access] In the case of overloaded function names, access control is - applied to the function selected by overloaded resolution. */ - if (rval && protect && !is_overloaded_fn (rval)) - perform_or_defer_access_check (basetype_path, rval); + applied to the function selected by overloaded resolution. + + We cannot check here, even if RVAL is only a single non-static + member function, since we do not know what the "this" pointer + will be. For: + + class A { protected: void f(); }; + class B : public A { + void g(A *p) { + f(); // OK + p->f(); // Not OK. + } + }; + + only the first call to "f" is valid. However, if the function is + static, we can check. */ + if (rval && protect + && !really_overloaded_fn (rval) + && !(TREE_CODE (rval) == FUNCTION_DECL + && DECL_NONSTATIC_MEMBER_FUNCTION_P (rval))) + perform_or_defer_access_check (basetype_path, rval, rval); if (errstr && protect) { @@ -1343,7 +1335,7 @@ lookup_conversion_operator (tree class_type, tree type) } /* TYPE is a class type. Return the index of the fields within - the method vector with name NAME, or -1 is no such field exists. */ + the method vector with name NAME, or -1 if no such field exists. */ int lookup_fnfields_1 (tree type, tree name) @@ -1366,10 +1358,16 @@ lookup_fnfields_1 (tree type, tree name) lazily_declare_fn (sfk_constructor, type); if (CLASSTYPE_LAZY_COPY_CTOR (type)) lazily_declare_fn (sfk_copy_constructor, type); + if (CLASSTYPE_LAZY_MOVE_CTOR (type)) + lazily_declare_fn (sfk_move_constructor, type); + } + else if (name == ansi_assopname (NOP_EXPR)) + { + if (CLASSTYPE_LAZY_COPY_ASSIGN (type)) + lazily_declare_fn (sfk_copy_assignment, type); + if (CLASSTYPE_LAZY_MOVE_ASSIGN (type)) + lazily_declare_fn (sfk_move_assignment, type); } - else if (name == ansi_assopname(NOP_EXPR) - && CLASSTYPE_LAZY_ASSIGNMENT_OP (type)) - lazily_declare_fn (sfk_assignment_operator, type); else if ((name == dtor_identifier || name == base_dtor_identifier || name == complete_dtor_identifier @@ -1447,6 +1445,18 @@ lookup_fnfields_1 (tree type, tree name) return -1; } +/* TYPE is a class type. Return the field within the method vector with + name NAME, or NULL_TREE if no such field exists. */ + +tree +lookup_fnfields_slot (tree type, tree name) +{ + int ix = lookup_fnfields_1 (type, name); + if (ix < 0) + return NULL_TREE; + return VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix); +} + /* Like lookup_fnfields_1, except that the name is extracted from FUNCTION, which is a FUNCTION_DECL or a TEMPLATE_DECL. */ @@ -1480,14 +1490,13 @@ adjust_result_of_qualified_name_lookup (tree decl, tree context_class) { if (context_class && context_class != error_mark_node + && CLASS_TYPE_P (context_class) && CLASS_TYPE_P (qualifying_scope) && DERIVED_FROM_P (qualifying_scope, context_class) && BASELINK_P (decl)) { tree base; - gcc_assert (CLASS_TYPE_P (context_class)); - /* Look for the QUALIFYING_SCOPE as a base of the CONTEXT_CLASS. Because we do not yet know which function will be chosen by overload resolution, we cannot yet check either accessibility @@ -1873,7 +1882,7 @@ check_final_overrider (tree overrider, tree basefn) } /* Check throw specifier is at least as strict. */ - if (!comp_except_specs (base_throw, over_throw, 0)) + if (!comp_except_specs (base_throw, over_throw, ce_derived)) { error ("looser throw specifier for %q+#F", overrider); error (" overriding %q+#F", basefn); @@ -1881,6 +1890,30 @@ check_final_overrider (tree overrider, tree basefn) return 0; } + /* Check for conflicting type attributes. */ + if (!targetm.comp_type_attributes (over_type, base_type)) + { + error ("conflicting type attributes specified for %q+#D", overrider); + error (" overriding %q+#D", basefn); + DECL_INVALID_OVERRIDER_P (overrider) = 1; + return 0; + } + + if (DECL_DELETED_FN (basefn) != DECL_DELETED_FN (overrider)) + { + if (DECL_DELETED_FN (overrider)) + { + error ("deleted function %q+D", overrider); + error ("overriding non-deleted function %q+D", basefn); + maybe_explain_implicit_delete (overrider); + } + else + { + error ("non-deleted function %q+D", overrider); + error ("overriding deleted function %q+D", basefn); + } + return 0; + } return 1; } @@ -1902,6 +1935,11 @@ look_for_overrides (tree type, tree fndecl) int ix; int found = 0; + /* A constructor for a class T does not override a function T + in a base class. */ + if (DECL_CONSTRUCTOR_P (fndecl)) + return 0; + for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++) { tree basetype = BINFO_TYPE (base_binfo); @@ -2402,10 +2440,13 @@ lookup_conversions_r (tree binfo, functions in this node were selected. This function is effectively performing a set of member lookups as lookup_fnfield does, but using the type being converted to as the unique key, rather than the - field name. */ + field name. + If LOOKUP_TEMPLATE_CONVS_P is TRUE, the returned TREE_LIST contains + the non-hidden user-defined template conversion functions too. */ tree -lookup_conversions (tree type) +lookup_conversions (tree type, + bool lookup_template_convs_p) { tree convs, tpl_convs; tree list = NULL_TREE; @@ -2432,6 +2473,9 @@ lookup_conversions (tree type) } } + if (lookup_template_convs_p == false) + tpl_convs = NULL_TREE; + for (; tpl_convs; tpl_convs = TREE_CHAIN (tpl_convs)) { tree probe, next;