/* 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, 2007, 2008
+ 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
#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 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 *);
\f
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);
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;
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)
#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++;
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);
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 <typename T> 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.
return 1;
if (is_overloaded_fn (t))
{
+ t = get_fns (t);
for (; t; t = OVL_NEXT (t))
{
tree fn = OVL_CURRENT (t);
}
}
- /* 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
/* 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
}
/* 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)
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
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. */
if (CLASS_TYPE_P (base_return) && CLASS_TYPE_P (over_return))
{
- tree binfo = lookup_base (over_return, base_return,
- ba_check | ba_quiet, NULL);
+ /* Strictly speaking, the standard requires the return type to be
+ complete even if it only differs in cv-quals, but that seems
+ like a bug in the wording. */
+ if (!same_type_ignoring_top_level_qualifiers_p (base_return, over_return))
+ {
+ tree binfo = lookup_base (over_return, base_return,
+ ba_check | ba_quiet, NULL);
- if (!binfo)
- fail = 1;
+ if (!binfo)
+ fail = 1;
+ }
}
else if (!pedantic
&& can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type)))
}
/* 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);
{
error ("deleted function %q+D", overrider);
error ("overriding non-deleted function %q+D", basefn);
+ maybe_explain_implicit_delete (overrider);
}
else
{
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);