OSDN Git Service

PR middle-end/42095
[pf3gnuchains/gcc-fork.git] / gcc / cp / tree.c
index 51752a3..17fc495 100644 (file)
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "convert.h"
 #include "tree-flow.h"
+#include "cgraph.h"
 
 static tree bot_manip (tree *, int *, void *);
 static tree bot_replace (tree *, int *, void *);
@@ -456,6 +457,22 @@ build_cplus_new (tree type, tree init)
   return rval;
 }
 
+/* Return a TARGET_EXPR which expresses the direct-initialization of one
+   array from another.  */
+
+tree
+build_array_copy (tree init)
+{
+  tree type = TREE_TYPE (init);
+  tree slot = build_local_temp (type);
+  init = build2 (VEC_INIT_EXPR, type, slot, init);
+  SET_EXPR_LOCATION (init, input_location);
+  init = build_target_expr (slot, init);
+  TARGET_EXPR_IMPLICIT_P (init) = 1;
+
+  return init;
+}
+
 /* Build a TARGET_EXPR using INIT to initialize a new temporary of the
    indicated TYPE.  */
 
@@ -539,8 +556,8 @@ rvalue (tree expr)
 
      Non-class rvalues always have cv-unqualified types.  */
   type = TREE_TYPE (expr);
-  if (!CLASS_TYPE_P (type) && cp_type_quals (type))
-    type = cp_build_qualified_type (type, TYPE_UNQUALIFIED);
+  if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
+    type = cv_unqualified (type);
 
   /* We need to do this for rvalue refs as well to get the right answer
      from decltype; see c++/36628.  */
@@ -623,7 +640,7 @@ build_cplus_array_type_1 (tree elt_type, tree index_type)
       else
        {
          /* Build a new array type.  */
-         t = make_node (ARRAY_TYPE);
+         t = cxx_make_type (ARRAY_TYPE);
          TREE_TYPE (t) = elt_type;
          TYPE_DOMAIN (t) = index_type;
 
@@ -726,6 +743,17 @@ cp_build_reference_type (tree to_type, bool rval)
 
 }
 
+/* Returns EXPR cast to rvalue reference type, like std::move.  */
+
+tree
+move (tree expr)
+{
+  tree type = TREE_TYPE (expr);
+  gcc_assert (TREE_CODE (type) != REFERENCE_TYPE);
+  type = cp_build_reference_type (type, /*rval*/true);
+  return build_static_cast (type, expr, tf_warning_or_error);
+}
+
 /* Used by the C++ front end to build qualified array types.  However,
    the C version of this function does not properly maintain canonical
    types (which are not used in C).  */
@@ -915,11 +943,20 @@ cp_build_qualified_type_real (tree type,
       && (TYPE_LANG_SPECIFIC (TYPE_CANONICAL (result)) 
           == TYPE_LANG_SPECIFIC (TYPE_CANONICAL (type))))
     TYPE_LANG_SPECIFIC (TYPE_CANONICAL (result)) = NULL;
-      
 
   return result;
 }
 
+/* Return TYPE with const and volatile removed.  */
+
+tree
+cv_unqualified (tree type)
+{
+  int quals = TYPE_QUALS (type);
+  quals &= ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
+  return cp_build_qualified_type (type, quals);
+}
+
 /* Builds a qualified variant of T that is not a typedef variant.
    E.g. consider the following declarations:
      typedef const int ConstInt;
@@ -1014,6 +1051,10 @@ strip_typedefs (tree t)
        else
            result = build_function_type (type,
                                          arg_types);
+
+       if (TYPE_RAISES_EXCEPTIONS (t))
+         result = build_exception_variant (result,
+                                           TYPE_RAISES_EXCEPTIONS (t));
       }
       break;
     default:
@@ -1022,9 +1063,19 @@ strip_typedefs (tree t)
 
   if (!result)
       result = TYPE_MAIN_VARIANT (t);
+  if (TYPE_ATTRIBUTES (t))
+    result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
   return cp_build_qualified_type (result, cp_type_quals (t));
 }
 
+/* Returns true iff TYPE is a type variant created for a typedef. */
+
+bool
+typedef_variant_p (tree type)
+{
+  return is_typedef_decl (TYPE_NAME (type));
+}
+
 \f
 /* Makes a copy of BINFO and TYPE, which is to be inherited into a
    graph dominated by T.  If BINFO is NULL, TYPE is a dependent base,
@@ -1258,6 +1309,8 @@ build_qualified_name (tree type, tree scope, tree name, bool template_p)
     return error_mark_node;
   t = build2 (SCOPE_REF, type, scope, name);
   QUALIFIED_NAME_IS_TEMPLATE (t) = template_p;
+  if (type)
+    t = convert_from_reference (t);
   return t;
 }
 
@@ -1438,8 +1491,7 @@ bind_template_template_parm (tree t, tree newargs)
   TEMPLATE_TYPE_PARM_INDEX (t2) = copy_node (TEMPLATE_TYPE_PARM_INDEX (t));
   TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (t2)) = decl;
   TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2)
-    = tree_cons (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t),
-                newargs, NULL_TREE);
+    = build_template_info (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t), newargs);
 
   TREE_TYPE (decl) = t2;
   TYPE_NAME (t2) = decl;
@@ -1530,28 +1582,18 @@ no_linkage_check (tree t, bool relaxed_p)
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (t))
        goto ptrmem;
+      /* Lambda types that don't have mangling scope have no linkage.  We
+        check CLASSTYPE_LAMBDA_EXPR here rather than LAMBDA_TYPE_P because
+        when we get here from pushtag none of the lambda information is
+        set up yet, so we want to assume that the lambda has linkage and
+        fix it up later if not.  */
+      if (CLASSTYPE_LAMBDA_EXPR (t)
+         && LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE)
+       return t;
       /* Fall through.  */
     case UNION_TYPE:
       if (!CLASS_TYPE_P (t))
        return NULL_TREE;
-
-      /* Check template type-arguments.  I think that types with no linkage
-         can't occur in non-type arguments, though that might change with
-         constexpr.  */
-      r = CLASSTYPE_TEMPLATE_INFO (t);
-      if (r)
-       {
-         tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (r));
-         int i;
-
-         for (i = TREE_VEC_LENGTH (args); i-- > 0; )
-           {
-             tree elt = TREE_VEC_ELT (args, i);
-             if (TYPE_P (elt)
-                 && (r = no_linkage_check (elt, relaxed_p), r))
-               return r;
-           }
-       }
       /* Fall through.  */
     case ENUMERAL_TYPE:
       /* Only treat anonymous types as having no linkage if they're at
@@ -1559,15 +1601,22 @@ no_linkage_check (tree t, bool relaxed_p)
       if (TYPE_ANONYMOUS_P (t) && TYPE_NAMESPACE_SCOPE_P (t))
        return t;
 
-      r = CP_TYPE_CONTEXT (t);
-      if (TYPE_P (r))
-       return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
-      else if (TREE_CODE (r) == FUNCTION_DECL)
+      for (r = CP_TYPE_CONTEXT (t); ; )
        {
-         if (!relaxed_p || !TREE_PUBLIC (r) || !vague_linkage_fn_p (r))
-           return t;
+         /* If we're a nested type of a !TREE_PUBLIC class, we might not
+            have linkage, or we might just be in an anonymous namespace.
+            If we're in a TREE_PUBLIC class, we have linkage.  */
+         if (TYPE_P (r) && !TREE_PUBLIC (TYPE_NAME (r)))
+           return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
+         else if (TREE_CODE (r) == FUNCTION_DECL)
+           {
+             if (!relaxed_p || !vague_linkage_fn_p (r))
+               return t;
+             else
+               r = CP_DECL_CONTEXT (r);
+           }
          else
-           return no_linkage_check (CP_DECL_CONTEXT (r), relaxed_p);
+           break;
        }
 
       return NULL_TREE;
@@ -2056,6 +2105,8 @@ cp_tree_equal (tree t1, tree t2)
     case TEMPLATE_PARM_INDEX:
       return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
              && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
+             && (TEMPLATE_PARM_PARAMETER_PACK (t1)
+                 == TEMPLATE_PARM_PARAMETER_PACK (t2))
              && same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
                              TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
 
@@ -2323,10 +2374,10 @@ trivial_type_p (const_tree t)
   t = strip_array_types (CONST_CAST_TREE (t));
 
   if (CLASS_TYPE_P (t))
-    return !(TYPE_HAS_COMPLEX_DFLT (t)
-            || TYPE_HAS_COMPLEX_INIT_REF (t)
-            || TYPE_HAS_COMPLEX_ASSIGN_REF (t)
-            || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t));
+    return (TYPE_HAS_TRIVIAL_DFLT (t)
+           && TYPE_HAS_TRIVIAL_INIT_REF (t)
+           && TYPE_HAS_TRIVIAL_ASSIGN_REF (t)
+           && TYPE_HAS_TRIVIAL_DESTRUCTOR (t));
   else
     return scalarish_type_p (t);
 }
@@ -2572,7 +2623,8 @@ cp_build_type_attribute_variant (tree type, tree attributes)
   tree new_type;
 
   new_type = build_type_attribute_variant (type, attributes);
-  if (TREE_CODE (new_type) == FUNCTION_TYPE
+  if ((TREE_CODE (new_type) == FUNCTION_TYPE
+       || TREE_CODE (new_type) == METHOD_TYPE)
       && (TYPE_RAISES_EXCEPTIONS (new_type)
          != TYPE_RAISES_EXCEPTIONS (type)))
     new_type = build_exception_variant (new_type,
@@ -2759,6 +2811,8 @@ special_function_p (const_tree decl)
      DECL_LANG_SPECIFIC.  */
   if (DECL_COPY_CONSTRUCTOR_P (decl))
     return sfk_copy_constructor;
+  if (DECL_MOVE_CONSTRUCTOR_P (decl))
+    return sfk_move_constructor;
   if (DECL_CONSTRUCTOR_P (decl))
     return sfk_constructor;
   if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
@@ -3072,7 +3126,16 @@ cp_fix_function_decl_p (tree decl)
   if (!gimple_has_body_p (decl)
       && !DECL_THUNK_P (decl)
       && !DECL_EXTERNAL (decl))
-    return true;
+    {
+      struct cgraph_node *node = cgraph_get_node (decl);
+
+      /* Don't fix same_body aliases.  Although they don't have their own
+        CFG, they share it with what they alias to.  */
+      if (!node
+         || node->decl == decl
+         || !node->same_body)
+       return true;
+    }
 
   return false;
 }
@@ -3102,6 +3165,17 @@ cp_free_lang_data (tree t)
       DECL_EXTERNAL (t) = 1;
       TREE_STATIC (t) = 0;
     }
+  if (CP_AGGREGATE_TYPE_P (t)
+      && TYPE_NAME (t))
+    {
+      tree name = TYPE_NAME (t);
+      if (TREE_CODE (name) == TYPE_DECL)
+       name = DECL_NAME (name);
+      /* Drop anonymous names.  */
+      if (name != NULL_TREE
+         && ANON_AGGRNAME_P (name))
+       TYPE_NAME (t) = NULL_TREE;
+    }
 }
 
 \f