OSDN Git Service

PR c++/43509
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index cc4317a..2fd6305 100644 (file)
@@ -114,24 +114,62 @@ tree
 build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
 {
   tree raises;
+  tree attrs;
   int type_quals;
 
   if (fntype == error_mark_node || ctype == error_mark_node)
     return error_mark_node;
 
+  gcc_assert (TREE_CODE (fntype) == FUNCTION_TYPE
+             || TREE_CODE (fntype) == METHOD_TYPE);
+
   type_quals = quals & ~TYPE_QUAL_RESTRICT;
   ctype = cp_build_qualified_type (ctype, type_quals);
+  raises = TYPE_RAISES_EXCEPTIONS (fntype);
+  attrs = TYPE_ATTRIBUTES (fntype);
   fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
                                       (TREE_CODE (fntype) == METHOD_TYPE
                                        ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
                                        : TYPE_ARG_TYPES (fntype)));
-  raises = TYPE_RAISES_EXCEPTIONS (fntype);
   if (raises)
     fntype = build_exception_variant (fntype, raises);
+  if (attrs)
+    fntype = cp_build_type_attribute_variant (fntype, attrs);
 
   return fntype;
 }
 
+/* Return a variant of FNTYPE, a FUNCTION_TYPE or METHOD_TYPE, with its
+   return type changed to NEW_RET.  */
+
+tree
+change_return_type (tree new_ret, tree fntype)
+{
+  tree newtype;
+  tree args = TYPE_ARG_TYPES (fntype);
+  tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
+  tree attrs = TYPE_ATTRIBUTES (fntype);
+
+  if (same_type_p (new_ret, TREE_TYPE (fntype)))
+    return fntype;
+
+  if (TREE_CODE (fntype) == FUNCTION_TYPE)
+    {
+      newtype = build_function_type (new_ret, args);
+      newtype = apply_memfn_quals (newtype, type_memfn_quals (fntype));
+    }
+  else
+    newtype = build_method_type_directly
+      (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
+       new_ret, TREE_CHAIN (args));
+  if (raises)
+    newtype = build_exception_variant (newtype, raises);
+  if (attrs)
+    newtype = cp_build_type_attribute_variant (newtype, attrs);
+
+  return newtype;
+}
+
 /* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE
    appropriately.  */
 
@@ -237,6 +275,9 @@ maybe_retrofit_in_chrg (tree fn)
   if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
     fntype = build_exception_variant (fntype,
                                      TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)));
+  if (TYPE_ATTRIBUTES (TREE_TYPE (fn)))
+    fntype = (cp_build_type_attribute_variant
+             (fntype, TYPE_ATTRIBUTES (TREE_TYPE (fn))));
   TREE_TYPE (fn) = fntype;
 
   /* Now we've got the in-charge parameter.  */
@@ -254,7 +295,7 @@ maybe_retrofit_in_chrg (tree fn)
    FUNCTION is a FUNCTION_DECL.  It was created by `grokdeclarator'.
 
    FLAGS contains bits saying what's special about today's
-   arguments.  1 == DESTRUCTOR.  2 == OPERATOR.
+   arguments.  DTOR_FLAG == DESTRUCTOR.
 
    If FUNCTION is a destructor, then we must add the `auto-delete' field
    as a second parameter.  There is some hair associated with the fact
@@ -747,6 +788,10 @@ finish_static_data_member_decl (tree decl,
   DECL_INITIAL (decl) = init;
   DECL_IN_AGGR_P (decl) = 1;
 
+  if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
+      && TYPE_DOMAIN (TREE_TYPE (decl)) == NULL_TREE)
+    SET_VAR_HAD_UNKNOWN_BOUND (decl);
+
   cp_finish_decl (decl, init, init_const_expr_p, asmspec_tree, flags);
 }
 
@@ -764,6 +809,7 @@ grokfield (const cp_declarator *declarator,
   tree value;
   const char *asmspec = 0;
   int flags = LOOKUP_ONLYCONVERTING;
+  tree name;
 
   if (init
       && TREE_CODE (init) == TREE_LIST
@@ -778,7 +824,7 @@ grokfield (const cp_declarator *declarator,
 
   if (TREE_CODE (value) == TYPE_DECL && init)
     {
-      error ("typedef %qD is initialized (use __typeof__ instead)", value);
+      error ("typedef %qD is initialized (use decltype instead)", value);
       init = NULL_TREE;
     }
 
@@ -792,11 +838,21 @@ grokfield (const cp_declarator *declarator,
       && DECL_CONTEXT (value) != current_class_type)
     return value;
 
-  if (DECL_NAME (value) != NULL_TREE
-      && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'
-      && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr"))
-    error ("member %qD conflicts with virtual function table field name",
-          value);
+  name = DECL_NAME (value);
+
+  if (name != NULL_TREE)
+    {
+      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+       {
+         error ("explicit template argument list not allowed");
+         return error_mark_node;
+       }
+
+      if (IDENTIFIER_POINTER (name)[0] == '_'
+         && ! strcmp (IDENTIFIER_POINTER (name), "_vptr"))
+       error ("member %qD conflicts with virtual function table field name",
+              value);
+    }
 
   /* Stash away type declarations.  */
   if (TREE_CODE (value) == TYPE_DECL)
@@ -823,7 +879,7 @@ grokfield (const cp_declarator *declarator,
       if (declspecs->specs[(int)ds_typedef]
           && TREE_TYPE (value) != error_mark_node
           && TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value))) != value)
-       set_underlying_type (value);
+       cp_set_underlying_type (value);
 
       return value;
     }
@@ -851,9 +907,7 @@ grokfield (const cp_declarator *declarator,
            }
          else if (init == ridpointers[(int)RID_DEFAULT])
            {
-             if (!defaultable_fn_p (value))
-               error ("%qD cannot be defaulted", value);
-             else
+             if (defaultable_fn_check (value))
                {
                  DECL_DEFAULTED_FN (value) = 1;
                  DECL_INITIALIZED_IN_CLASS_P (value) = 1;
@@ -862,8 +916,13 @@ grokfield (const cp_declarator *declarator,
            }
          else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
            {
-             gcc_assert (error_operand_p (init) || integer_zerop (init));
-             DECL_PURE_VIRTUAL_P (value) = 1;
+             if (integer_zerop (init))
+               DECL_PURE_VIRTUAL_P (value) = 1;
+             else if (error_operand_p (init))
+               ; /* An error has already been reported.  */
+             else
+               error ("invalid initializer for member function %qD",
+                      value);
            }
          else
            {
@@ -1190,6 +1249,7 @@ cp_reconstruct_complex_type (tree type, tree bottom)
     {
       inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
       outer = build_function_type (inner, TYPE_ARG_TYPES (type));
+      outer = apply_memfn_quals (outer, type_memfn_quals (type));
     }
   else if (TREE_CODE (type) == METHOD_TYPE)
     {
@@ -1210,7 +1270,9 @@ cp_reconstruct_complex_type (tree type, tree bottom)
   else
     return bottom;
 
-  return cp_build_qualified_type (outer, TYPE_QUALS (type));
+  if (TYPE_ATTRIBUTES (type))
+    outer = cp_build_type_attribute_variant (outer, TYPE_ATTRIBUTES (type));
+  return cp_build_qualified_type (outer, cp_type_quals (type));
 }
 
 /* Like decl_attributes, but handle C++ complexity.  */
@@ -1292,6 +1354,7 @@ build_anon_union_vars (tree type, tree object)
          decl = build_decl (input_location,
                             VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
          DECL_ANON_UNION_VAR_P (decl) = 1;
+         DECL_ARTIFICIAL (decl) = 1;
 
          base = get_base_address (object);
          TREE_PUBLIC (decl) = TREE_PUBLIC (base);
@@ -1552,8 +1615,7 @@ comdat_linkage (tree decl)
        }
     }
 
-  if (DECL_LANG_SPECIFIC (decl))
-    DECL_COMDAT (decl) = 1;
+  DECL_COMDAT (decl) = 1;
 }
 
 /* For win32 we also want to put explicit instantiations in
@@ -1594,6 +1656,24 @@ maybe_make_one_only (tree decl)
     }
 }
 
+/* Returns true iff DECL, a FUNCTION_DECL or VAR_DECL, has vague linkage.
+   This predicate will give the right answer during parsing of the
+   function, which other tests may not.  */
+
+bool
+vague_linkage_p (tree decl)
+{
+  /* Unfortunately, import_export_decl has not always been called
+     before the function is processed, so we cannot simply check
+     DECL_COMDAT.  */
+  return (DECL_COMDAT (decl)
+         || (((TREE_CODE (decl) == FUNCTION_DECL
+               && DECL_DECLARED_INLINE_P (decl))
+              || (DECL_LANG_SPECIFIC (decl)
+                  && DECL_TEMPLATE_INSTANTIATION (decl)))
+             && TREE_PUBLIC (decl)));
+}
+
 /* Determine whether or not we want to specifically import or export CTYPE,
    using various heuristics.  */
 
@@ -1728,6 +1808,7 @@ maybe_emit_vtables (tree ctype)
   tree vtbl;
   tree primary_vtbl;
   int needed = 0;
+  struct varpool_node *current = NULL, *last = NULL, *first = NULL;
 
   /* If the vtables for this class have already been emitted there is
      nothing more to do.  */
@@ -1785,8 +1866,20 @@ maybe_emit_vtables (tree ctype)
         actually marking the variable as written.  */
       if (flag_syntax_only)
        TREE_ASM_WRITTEN (vtbl) = 1;
+      else if (DECL_COMDAT (vtbl))
+       {
+         current = varpool_node (vtbl);
+         if (last)
+           last->same_comdat_group = current;
+         last = current;
+         if (!first)
+           first = current;
+       }
     }
 
+  if (first != last)
+    last->same_comdat_group = first;
+
   /* Since we're writing out the vtable here, also write the debug
      info.  */
   note_debug_info_needed (ctype);
@@ -1846,6 +1939,8 @@ constrain_visibility (tree decl, int visibility)
       if (!DECL_EXTERN_C_P (decl))
        {
          TREE_PUBLIC (decl) = 0;
+         DECL_WEAK (decl) = 0;
+         DECL_COMMON (decl) = 0;
          DECL_COMDAT_GROUP (decl) = NULL_TREE;
          DECL_INTERFACE_KNOWN (decl) = 1;
          if (DECL_LANG_SPECIFIC (decl))
@@ -2064,6 +2159,16 @@ determine_visibility (tree decl)
          || ! DECL_VISIBILITY_SPECIFIED (decl))
        constrain_visibility (decl, tvis);
     }
+  else if (no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/true))
+    /* DR 757: A type without linkage shall not be used as the type of a
+       variable or function with linkage, unless
+       o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
+       o the variable or function is not used (3.2 [basic.def.odr]) or is
+       defined in the same translation unit.
+
+       Since non-extern "C" decls need to be defined in the same
+       translation unit, we can make the type internal.  */
+    constrain_visibility (decl, VISIBILITY_ANON);
 
   /* If visibility changed and DECL already has DECL_RTL, ensure
      symbol flags are updated.  */
@@ -2505,7 +2610,9 @@ get_guard (tree decl)
       TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
       TREE_STATIC (guard) = TREE_STATIC (decl);
       DECL_COMMON (guard) = DECL_COMMON (decl);
-      DECL_COMDAT_GROUP (guard) = DECL_COMDAT_GROUP (decl);
+      DECL_COMDAT (guard) = DECL_COMDAT (decl);
+      if (DECL_ONE_ONLY (decl))
+       make_decl_one_only (guard, cxx_comdat_group (guard));
       if (TREE_PUBLIC (decl))
        DECL_WEAK (guard) = DECL_WEAK (decl);
       DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
@@ -3264,18 +3371,9 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED)
        cgraph_mark_address_taken_node (cgraph_node (BASELINK_FUNCTIONS (t)));
       break;
     case VAR_DECL:
-      if (DECL_VTABLE_OR_VTT_P (t))
-       {
-         /* The ABI requires that all virtual tables be emitted
-            whenever one of them is.  */
-         tree vtbl;
-         for (vtbl = CLASSTYPE_VTABLES (DECL_CONTEXT (t));
-              vtbl;
-              vtbl = TREE_CHAIN (vtbl))
-           mark_decl_referenced (vtbl);
-       }
-      else if (DECL_CONTEXT (t)
-              && TREE_CODE (DECL_CONTEXT (t)) == FUNCTION_DECL)
+      if (DECL_CONTEXT (t)
+         && flag_use_repository
+         && TREE_CODE (DECL_CONTEXT (t)) == FUNCTION_DECL)
        /* If we need a static variable in a function, then we
           need the containing function.  */
        mark_decl_referenced (DECL_CONTEXT (t));
@@ -3607,7 +3705,36 @@ cp_write_global_declarations (void)
          if (DECL_NOT_REALLY_EXTERN (decl)
              && DECL_INITIAL (decl)
              && decl_needed_p (decl))
-           DECL_EXTERNAL (decl) = 0;
+           {
+             struct cgraph_node *node = cgraph_get_node (decl), *alias, *next;
+
+             DECL_EXTERNAL (decl) = 0;
+             /* If we mark !DECL_EXTERNAL one of the same body aliases,
+                we need to mark all of them that way.  */
+             if (node && node->same_body)
+               {
+                 DECL_EXTERNAL (node->decl) = 0;
+                 for (alias = node->same_body; alias; alias = alias->next)
+                   DECL_EXTERNAL (alias->decl) = 0;
+               }
+             /* If we mark !DECL_EXTERNAL one of the symbols in some comdat
+                group, we need to mark all symbols in the same comdat group
+                that way.  */
+             if (node->same_comdat_group)
+               for (next = node->same_comdat_group;
+                    next != node;
+                    next = next->same_comdat_group)
+                 {
+                   DECL_EXTERNAL (next->decl) = 0;
+                   if (next->same_body)
+                     {
+                       for (alias = next->same_body;
+                            alias;
+                            alias = alias->next)
+                         DECL_EXTERNAL (alias->decl) = 0;
+                     }
+                 }
+           }
 
          /* If we're going to need to write this function out, and
             there's already a body for it, create RTL for it now.
@@ -3891,6 +4018,18 @@ mark_used (tree decl)
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DELETED_FN (decl))
     {
+      if (DECL_ARTIFICIAL (decl))
+       {
+         if (DECL_OVERLOADED_OPERATOR_P (decl) == TYPE_EXPR
+             && LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
+           {
+             /* We mark a lambda conversion op as deleted if we can't
+                generate it properly; see maybe_add_lambda_conv_op.  */
+             sorry ("converting lambda which uses %<...%> to "
+                    "function pointer");
+             return;
+           }
+       }
       error ("deleted function %q+D", decl);
       error ("used here");
       return;
@@ -3955,7 +4094,8 @@ mark_used (tree decl)
    o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
    o the variable or function is not used (3.2 [basic.def.odr]) or is
    defined in the same translation unit.  */
-  if (TREE_PUBLIC (decl)
+  if (cxx_dialect > cxx98
+      && decl_linkage (decl) != lk_none
       && !DECL_EXTERN_C_P (decl)
       && !DECL_ARTIFICIAL (decl)
       && !decl_defined_p (decl)