X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcp%2Fsearch.c;h=11011e7f3347e229bcca283a946aac3f226697c3;hp=795e8c2e44f0dc2fdb0e992d0c3133bf2071bc31;hb=943745698ae00632c65c5a25b77b276b00000bd1;hpb=3cf8b391b5f30be2e0c5404396abcfa20d88751e
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 795e8c2e44f..11011e7f334 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,13 @@ Boston, MA 02110-1301, USA. */
#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
+#include "intl.h"
#include "obstack.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 +64,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 *);
@@ -97,7 +98,7 @@ struct lookup_base_data_s
static tree
dfs_lookup_base (tree binfo, void *data_)
{
- struct lookup_base_data_s *data = data_;
+ struct lookup_base_data_s *data = (struct lookup_base_data_s *) data_;
if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->base))
{
@@ -213,9 +214,12 @@ 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_TYPE_P (base) || TYPE_BEING_DEFINED (base)))
{
struct lookup_base_data_s data;
@@ -306,7 +310,7 @@ struct dcast_data_s
static tree
dfs_dcast_hint_pre (tree binfo, void *data_)
{
- struct dcast_data_s *data = data_;
+ struct dcast_data_s *data = (struct dcast_data_s *) data_;
if (BINFO_VIRTUAL_P (binfo))
data->virt_depth++;
@@ -334,7 +338,7 @@ dfs_dcast_hint_pre (tree binfo, void *data_)
static tree
dfs_dcast_hint_post (tree binfo, void *data_)
{
- struct dcast_data_s *data = data_;
+ struct dcast_data_s *data = (struct dcast_data_s *) data_;
if (BINFO_VIRTUAL_P (binfo))
data->virt_depth--;
@@ -394,12 +398,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)
@@ -720,20 +722,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 +787,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))
@@ -872,8 +867,12 @@ accessible_p (tree type, tree decl, bool consider_local_p)
/* In a template declaration, we cannot be sure whether the
particular specialization that is instantiated will be a friend
or not. Therefore, all access checks are deferred until
- instantiation. */
- if (processing_template_decl)
+ instantiation. However, PROCESSING_TEMPLATE_DECL is set in the
+ parameter list for a template (because we may see dependent types
+ in default arguments for template parameters), and access
+ checking should be performed in the outermost parameter list. */
+ if (processing_template_decl
+ && (!processing_template_parmlist || processing_template_decl > 1))
return 1;
if (!TYPE_P (type))
@@ -956,24 +955,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.
@@ -992,6 +973,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);
@@ -1093,11 +1075,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
@@ -1126,7 +1103,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
@@ -1196,6 +1173,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)
@@ -1205,7 +1185,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;
}
@@ -1248,9 +1229,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)
{
@@ -1362,6 +1361,8 @@ 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)
&& CLASSTYPE_LAZY_ASSIGNMENT_OP (type))
@@ -1475,14 +1476,14 @@ adjust_result_of_qualified_name_lookup (tree decl,
tree qualifying_scope,
tree context_class)
{
- if (context_class && CLASS_TYPE_P (qualifying_scope)
+ 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
@@ -1876,6 +1877,29 @@ 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);
+ }
+ else
+ {
+ error ("non-deleted function %q+D", overrider);
+ error ("overriding deleted function %q+D", basefn);
+ }
+ return 0;
+ }
return 1;
}
@@ -2038,6 +2062,10 @@ maybe_suppress_debug_info (tree t)
/* We might have set this earlier in cp_finish_decl. */
TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 0;
+ /* Always emit the information for each class every time. */
+ if (flag_emit_class_debug_always)
+ return;
+
/* If we already know how we're handling this class, handle debug info
the same way. */
if (CLASSTYPE_INTERFACE_KNOWN (t))
@@ -2351,7 +2379,7 @@ lookup_conversions_r (tree binfo,
{
parent_tpl_convs = tree_cons (binfo, my_tpl_convs, parent_tpl_convs);
if (virtual_depth)
- TREE_STATIC (parent_convs) = 1;
+ TREE_STATIC (parent_tpl_convs) = 1;
}
child_convs = other_convs;
@@ -2393,10 +2421,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;
@@ -2423,6 +2454,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;