Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / gcc / cp / search.c
index e48dcec..54a5e4a 100644 (file)
@@ -1,8 +1,6 @@
 /* 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, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1987-2013 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -31,7 +29,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "cp-tree.h"
 #include "intl.h"
 #include "flags.h"
-#include "output.h"
 #include "toplev.h"
 #include "target.h"
 
@@ -66,14 +63,12 @@ static tree dfs_get_pure_virtuals (tree, void *);
 
 \f
 /* Variables for gathering statistics.  */
-#ifdef GATHER_STATISTICS
 static int n_fields_searched;
 static int n_calls_lookup_field, n_calls_lookup_field_1;
 static int n_calls_lookup_fnfields, n_calls_lookup_fnfields_1;
 static int n_calls_get_base_type;
 static int n_outer_fields_searched;
 static int n_contexts_saved;
-#endif /* GATHER_STATISTICS */
 
 \f
 /* Data for lookup_base and its workers.  */
@@ -181,18 +176,26 @@ accessible_base_p (tree t, tree base, bool consider_local_p)
    non-NULL, fill with information about what kind of base we
    discovered.
 
-   If the base is inaccessible, or ambiguous, and the ba_quiet bit is
-   not set in ACCESS, then an error is issued and error_mark_node is
-   returned.  If the ba_quiet bit is set, then no error is issued and
-   NULL_TREE is returned.  */
+   If the base is inaccessible, or ambiguous, then error_mark_node is
+   returned.  If the tf_error bit of COMPLAIN is not set, no error
+   is issued.  */
 
 tree
-lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
+lookup_base (tree t, tree base, base_access access,
+            base_kind *kind_ptr, tsubst_flags_t complain)
 {
   tree binfo;
   tree t_binfo;
   base_kind bk;
 
+  /* "Nothing" is definitely not derived from Base.  */
+  if (t == NULL_TREE)
+    {
+      if (kind_ptr)
+       *kind_ptr = bk_not_base;
+      return NULL_TREE;
+    }
+
   if (t == error_mark_node || base == error_mark_node)
     {
       if (kind_ptr)
@@ -253,11 +256,9 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
        break;
 
       case bk_ambig:
-       if (!(access & ba_quiet))
-         {
-           error ("%qT is an ambiguous base of %qT", base, t);
-           binfo = error_mark_node;
-         }
+       if (complain & tf_error)
+         error ("%qT is an ambiguous base of %qT", base, t);
+       binfo = error_mark_node;
        break;
 
       default:
@@ -271,13 +272,9 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
            && COMPLETE_TYPE_P (base)
            && !accessible_base_p (t, base, !(access & ba_ignore_scope)))
          {
-           if (!(access & ba_quiet))
-             {
-               error ("%qT is an inaccessible base of %qT", base, t);
-               binfo = error_mark_node;
-             }
-           else
-             binfo = NULL_TREE;
+           if (complain & tf_error)
+             error ("%qT is an inaccessible base of %qT", base, t);
+           binfo = error_mark_node;
            bk = bk_inaccessible;
          }
        break;
@@ -384,6 +381,8 @@ lookup_field_1 (tree type, tree name, bool want_type)
 {
   tree field;
 
+  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+
   if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
       || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
       || TREE_CODE (type) == TYPENAME_TYPE)
@@ -405,9 +404,8 @@ lookup_field_1 (tree type, tree name, bool want_type)
        {
          i = (lo + hi) / 2;
 
-#ifdef GATHER_STATISTICS
-         n_fields_searched++;
-#endif /* GATHER_STATISTICS */
+         if (GATHER_STATISTICS)
+           n_fields_searched++;
 
          if (DECL_NAME (fields[i]) > name)
            hi = i;
@@ -452,16 +450,16 @@ lookup_field_1 (tree type, tree name, bool want_type)
 
   field = TYPE_FIELDS (type);
 
-#ifdef GATHER_STATISTICS
-  n_calls_lookup_field_1++;
-#endif /* GATHER_STATISTICS */
+  if (GATHER_STATISTICS)
+    n_calls_lookup_field_1++;
+
   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
     {
       tree decl = field;
 
-#ifdef GATHER_STATISTICS
-      n_fields_searched++;
-#endif /* GATHER_STATISTICS */
+      if (GATHER_STATISTICS)
+       n_fields_searched++;
+
       gcc_assert (DECL_P (field));
       if (DECL_NAME (field) == NULL_TREE
          && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
@@ -577,7 +575,8 @@ context_for_name_lookup (tree decl)
      declared.  */
   tree context = DECL_CONTEXT (decl);
 
-  while (context && TYPE_P (context) && ANON_AGGR_TYPE_P (context))
+  while (context && TYPE_P (context)
+        && (ANON_AGGR_TYPE_P (context) || UNSCOPED_ENUM_P (context)))
     context = TYPE_CONTEXT (context);
   if (!context)
     context = global_namespace;
@@ -621,9 +620,7 @@ dfs_access_in_type (tree binfo, void *data)
   else
     {
       /* First, check for an access-declaration that gives us more
-        access to the DECL.  The CONST_DECL for an enumeration
-        constant will not have DECL_LANG_SPECIFIC, and thus no
-        DECL_ACCESS.  */
+        access to the DECL.  */
       if (DECL_LANG_SPECIFIC (decl) && !DECL_DISCRIMINATOR_P (decl))
        {
          tree decl_access = purpose_member (type, DECL_ACCESS (decl));
@@ -647,14 +644,14 @@ dfs_access_in_type (tree binfo, void *data)
        {
          int i;
          tree base_binfo;
-         VEC(tree,gc) *accesses;
+         vec<tree, va_gc> *accesses;
 
          /* Otherwise, scan our baseclasses, and pick the most favorable
             access.  */
          accesses = BINFO_BASE_ACCESSES (binfo);
          for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
            {
-             tree base_access = VEC_index (tree, accesses, i);
+             tree base_access = (*accesses)[i];
              access_kind base_access_now = BINFO_ACCESS (base_binfo);
 
              if (base_access_now == ak_none || base_access_now == ak_private)
@@ -827,7 +824,7 @@ friend_accessible_p (tree scope, tree decl, tree binfo)
 /* Called via dfs_walk_once_accessible from accessible_p */
 
 static tree
-dfs_accessible_post (tree binfo, void *data ATTRIBUTE_UNUSED)
+dfs_accessible_post (tree binfo, void * /*data*/)
 {
   if (BINFO_ACCESS (binfo) != ak_none)
     {
@@ -840,6 +837,19 @@ dfs_accessible_post (tree binfo, void *data ATTRIBUTE_UNUSED)
   return NULL_TREE;
 }
 
+/* Like accessible_p below, but within a template returns true iff DECL is
+   accessible in TYPE to all possible instantiations of the template.  */
+
+int
+accessible_in_template_p (tree type, tree decl)
+{
+  int save_ptd = processing_template_decl;
+  processing_template_decl = 0;
+  int val = accessible_p (type, decl, false);
+  processing_template_decl = save_ptd;
+  return val;
+}
+
 /* DECL is a declaration from a base class of TYPE, which was the
    class used to name DECL.  Return nonzero if, in the current
    context, DECL is accessible.  If TYPE is actually a BINFO node,
@@ -1202,9 +1212,8 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type,
   if (!basetype_path)
     return NULL_TREE;
 
-#ifdef GATHER_STATISTICS
-  n_calls_lookup_field++;
-#endif /* GATHER_STATISTICS */
+  if (GATHER_STATISTICS)
+    n_calls_lookup_field++;
 
   memset (&lfi, 0, sizeof (lfi));
   lfi.type = type;
@@ -1250,10 +1259,14 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type,
     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);
+      && !really_overloaded_fn (rval))
+    {
+      tree decl = is_overloaded_fn (rval) ? get_first_fn (rval) : rval;
+      if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
+         && !perform_or_defer_access_check (basetype_path, decl, decl,
+                                            complain))
+       rval = error_mark_node;
+    }
 
   if (errstr && protect)
     {
@@ -1321,10 +1334,10 @@ lookup_conversion_operator (tree class_type, tree type)
     {
       int i;
       tree fn;
-      VEC(tree,gc) *methods = CLASSTYPE_METHOD_VEC (class_type);
+      vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (class_type);
 
       for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
-          VEC_iterate (tree, methods, i, fn); ++i)
+          vec_safe_iterate (methods, i, &fn); ++i)
        {
          /* All the conversion operators come near the beginning of
             the class.  Therefore, if FN is not a conversion
@@ -1353,7 +1366,7 @@ lookup_conversion_operator (tree class_type, tree type)
 static int
 lookup_fnfields_idx_nolazy (tree type, tree name)
 {
-  VEC(tree,gc) *method_vec;
+  vec<tree, va_gc> *method_vec;
   tree fn;
   tree tmp;
   size_t i;
@@ -1365,9 +1378,8 @@ lookup_fnfields_idx_nolazy (tree type, tree name)
   if (!method_vec)
     return -1;
 
-#ifdef GATHER_STATISTICS
-  n_calls_lookup_fnfields_1++;
-#endif /* GATHER_STATISTICS */
+  if (GATHER_STATISTICS)
+    n_calls_lookup_fnfields_1++;
 
   /* Constructors are first...  */
   if (name == ctor_identifier)
@@ -1386,7 +1398,7 @@ lookup_fnfields_idx_nolazy (tree type, tree name)
 
   /* Skip the conversion operators.  */
   for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
-       VEC_iterate (tree, method_vec, i, fn);
+       vec_safe_iterate (method_vec, i, &fn);
        ++i)
     if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
       break;
@@ -1398,16 +1410,15 @@ lookup_fnfields_idx_nolazy (tree type, tree name)
       int hi;
 
       lo = i;
-      hi = VEC_length (tree, method_vec);
+      hi = method_vec->length ();
       while (lo < hi)
        {
          i = (lo + hi) / 2;
 
-#ifdef GATHER_STATISTICS
-         n_outer_fields_searched++;
-#endif /* GATHER_STATISTICS */
+         if (GATHER_STATISTICS)
+           n_outer_fields_searched++;
 
-         tmp = VEC_index (tree, method_vec, i);
+         tmp = (*method_vec)[i];
          tmp = DECL_NAME (OVL_CURRENT (tmp));
          if (tmp > name)
            hi = i;
@@ -1418,11 +1429,10 @@ lookup_fnfields_idx_nolazy (tree type, tree name)
        }
     }
   else
-    for (; VEC_iterate (tree, method_vec, i, fn); ++i)
+    for (; vec_safe_iterate (method_vec, i, &fn); ++i)
       {
-#ifdef GATHER_STATISTICS
-       n_outer_fields_searched++;
-#endif /* GATHER_STATISTICS */
+       if (GATHER_STATISTICS)
+         n_outer_fields_searched++;
        if (DECL_NAME (OVL_CURRENT (fn)) == name)
          return i;
       }
@@ -1479,7 +1489,7 @@ lookup_fnfields_slot (tree type, tree name)
   int ix = lookup_fnfields_1 (complete_type (type), name);
   if (ix < 0)
     return NULL_TREE;
-  return VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
+  return (*CLASSTYPE_METHOD_VEC (type))[ix];
 }
 
 /* As above, but avoid lazily declaring functions.  */
@@ -1490,7 +1500,7 @@ lookup_fnfields_slot_nolazy (tree type, tree name)
   int ix = lookup_fnfields_idx_nolazy (complete_type (type), name);
   if (ix < 0)
     return NULL_TREE;
-  return VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
+  return (*CLASSTYPE_METHOD_VEC (type))[ix];
 }
 
 /* Like lookup_fnfields_1, except that the name is extracted from
@@ -1539,14 +1549,13 @@ adjust_result_of_qualified_name_lookup (tree decl,
         or ambiguity -- in either case, the choice of a static member
         function might make the usage valid.  */
       base = lookup_base (context_class, qualifying_scope,
-                         ba_unique | ba_quiet, NULL);
-      if (base)
+                         ba_unique, NULL, tf_none);
+      if (base && base != error_mark_node)
        {
          BASELINK_ACCESS_BINFO (decl) = base;
          BASELINK_BINFO (decl)
            = lookup_base (base, BINFO_TYPE (BASELINK_BINFO (decl)),
-                          ba_unique | ba_quiet,
-                          NULL);
+                          ba_unique, NULL, tf_none);
        }
     }
 
@@ -1710,12 +1719,12 @@ dfs_walk_once (tree binfo, tree (*pre_fn) (tree, void *),
          /* We are at the top of the hierarchy, and can use the
             CLASSTYPE_VBASECLASSES list for unmarking the virtual
             bases.  */
-         VEC(tree,gc) *vbases;
+         vec<tree, va_gc> *vbases;
          unsigned ix;
          tree base_binfo;
 
          for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
-              VEC_iterate (tree, vbases, ix, base_binfo); ix++)
+              vec_safe_iterate (vbases, ix, &base_binfo); ix++)
            BINFO_MARKED (base_binfo) = 0;
        }
       else
@@ -1818,12 +1827,12 @@ dfs_walk_once_accessible (tree binfo, bool friends_p,
          /* We are at the top of the hierarchy, and can use the
             CLASSTYPE_VBASECLASSES list for unmarking the virtual
             bases.  */
-         VEC(tree,gc) *vbases;
+         vec<tree, va_gc> *vbases;
          unsigned ix;
          tree base_binfo;
 
          for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
-              VEC_iterate (tree, vbases, ix, base_binfo); ix++)
+              vec_safe_iterate (vbases, ix, &base_binfo); ix++)
            BINFO_MARKED (base_binfo) = 0;
        }
       else
@@ -1877,17 +1886,19 @@ check_final_overrider (tree overrider, tree basefn)
          /* 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))
+         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);
+                                       ba_check, NULL, tf_none);
 
-             if (!binfo)
+             if (!binfo || binfo == error_mark_node)
                fail = 1;
            }
        }
       else if (!pedantic
-              && can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type)))
+              && can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type),
+                              tf_warning_or_error))
        /* GNU extension, allow trivial pointer conversions such as
           converting to void *, or qualification conversion.  */
        {
@@ -2026,7 +2037,7 @@ look_for_overrides_here (tree type, tree fndecl)
     ix = lookup_fnfields_1 (type, DECL_NAME (fndecl));
   if (ix >= 0)
     {
-      tree fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
+      tree fns = (*CLASSTYPE_METHOD_VEC (type))[ix];
 
       for (; fns; fns = OVL_NEXT (fns))
        {
@@ -2097,8 +2108,7 @@ dfs_get_pure_virtuals (tree binfo, void *data)
           virtuals;
           virtuals = TREE_CHAIN (virtuals))
        if (DECL_PURE_VIRTUAL_P (BV_FN (virtuals)))
-         VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (type),
-                        BV_FN (virtuals));
+         vec_safe_push (CLASSTYPE_PURE_VIRTUALS (type), BV_FN (virtuals));
     }
 
   return NULL_TREE;
@@ -2167,7 +2177,7 @@ maybe_suppress_debug_info (tree t)
    information anyway.  */
 
 static tree
-dfs_debug_mark (tree binfo, void *data ATTRIBUTE_UNUSED)
+dfs_debug_mark (tree binfo, void * /*data*/)
 {
   tree t = BINFO_TYPE (binfo);
 
@@ -2201,28 +2211,28 @@ note_debug_info_needed (tree type)
 void
 print_search_statistics (void)
 {
-#ifdef GATHER_STATISTICS
+  if (! GATHER_STATISTICS)
+    {
+      fprintf (stderr, "no search statistics\n");
+      return;
+    }
+
   fprintf (stderr, "%d fields searched in %d[%d] calls to lookup_field[_1]\n",
           n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1);
   fprintf (stderr, "%d fnfields searched in %d calls to lookup_fnfields\n",
           n_outer_fields_searched, n_calls_lookup_fnfields);
   fprintf (stderr, "%d calls to get_base_type\n", n_calls_get_base_type);
-#else /* GATHER_STATISTICS */
-  fprintf (stderr, "no search statistics\n");
-#endif /* GATHER_STATISTICS */
 }
 
 void
 reinit_search_statistics (void)
 {
-#ifdef GATHER_STATISTICS
   n_fields_searched = 0;
   n_calls_lookup_field = 0, n_calls_lookup_field_1 = 0;
   n_calls_lookup_fnfields = 0, n_calls_lookup_fnfields_1 = 0;
   n_calls_get_base_type = 0;
   n_outer_fields_searched = 0;
   n_contexts_saved = 0;
-#endif /* GATHER_STATISTICS */
 }
 
 /* Helper for lookup_conversions_r.  TO_TYPE is the type converted to
@@ -2371,7 +2381,7 @@ lookup_conversions_r (tree binfo,
   tree child_tpl_convs = NULL_TREE;
   unsigned i;
   tree base_binfo;
-  VEC(tree,gc) *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
+  vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
   tree conv;
 
   /* If we have no conversion operators, then don't look.  */
@@ -2387,7 +2397,7 @@ lookup_conversions_r (tree binfo,
 
   /* First, locate the unhidden ones at this level.  */
   for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
-       VEC_iterate (tree, method_vec, i, conv);
+       vec_safe_iterate (method_vec, i, &conv);
        ++i)
     {
       tree cur = OVL_CURRENT (conv);
@@ -2426,6 +2436,11 @@ lookup_conversions_r (tree binfo,
          if (!IDENTIFIER_MARKED (name))
            {
              tree type = DECL_CONV_FN_TYPE (cur);
+             if (type_uses_auto (type))
+               {
+                 mark_used (cur);
+                 type = DECL_CONV_FN_TYPE (cur);
+               }
 
              if (check_hidden_convs (binfo, virtual_depth, virtualness,
                                      type, parent_convs, other_convs))
@@ -2624,10 +2639,10 @@ binfo_for_vbase (tree base, tree t)
 {
   unsigned ix;
   tree binfo;
-  VEC(tree,gc) *vbases;
+  vec<tree, va_gc> *vbases;
 
   for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
-       VEC_iterate (tree, vbases, ix, binfo); ix++)
+       vec_safe_iterate (vbases, ix, &binfo); ix++)
     if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), base))
       return binfo;
   return NULL;