OSDN Git Service

* decl.c (get_atexit_fn_ptr_type): New function.
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index 11c4901..3e18c4a 100644 (file)
@@ -97,11 +97,6 @@ static GTY(()) VEC(tree,gc) *deferred_fns;
 
 int at_eof;
 
-/* Functions called along with real static constructors and destructors.  */
-
-tree static_ctors;
-tree static_dtors;
-
 \f
 
 /* Return a member function type (a METHOD_TYPE), given FNTYPE (a
@@ -141,6 +136,12 @@ cp_build_parm_decl (tree name, tree type)
      sees templates.  */
   if (!processing_template_decl)
     DECL_ARG_TYPE (parm) = type_passed_as (type);
+
+  /* If the type is a pack expansion, then we have a function
+     parameter pack. */
+  if (type && TREE_CODE (type) == TYPE_PACK_EXPANSION)
+    FUNCTION_PARAMETER_PACK_P (parm) = 1;
+
   return parm;
 }
 
@@ -445,13 +446,8 @@ check_member_template (tree tmpl)
       || (TREE_CODE (decl) == TYPE_DECL
          && IS_AGGR_TYPE (TREE_TYPE (decl))))
     {
-      if (current_function_decl)
-       /* 14.5.2.2 [temp.mem]
-
-          A local class shall not have member templates.  */
-       error ("invalid declaration of member template %q#D in local class",
-              decl);
-
+      /* The parser rejects template declarations in local classes.  */
+      gcc_assert (!current_function_decl);
       /* The parser rejects any use of virtual in a function template.  */
       gcc_assert (!(TREE_CODE (decl) == FUNCTION_DECL
                    && DECL_VIRTUAL_P (decl)));
@@ -469,8 +465,11 @@ check_member_template (tree tmpl)
 static bool
 acceptable_java_type (tree type)
 {
+  if (type == error_mark_node)
+    return false;
+
   if (TREE_CODE (type) == VOID_TYPE || TYPE_FOR_JAVA (type))
-    return 1;
+    return true;
   if (TREE_CODE (type) == POINTER_TYPE || TREE_CODE (type) == REFERENCE_TYPE)
     {
       type = TREE_TYPE (type);
@@ -526,8 +525,9 @@ check_java_method (tree method)
       tree type = TREE_VALUE (arg_types);
       if (!acceptable_java_type (type))
        {
-         error ("Java method %qD has non-Java parameter type %qT",
-                method, type);
+          if (type != error_mark_node)
+           error ("Java method %qD has non-Java parameter type %qT",
+                  method, type);
          jerr = true;
        }
     }
@@ -549,7 +549,8 @@ check_classfn (tree ctype, tree function, tree template_parms)
 {
   int ix;
   bool is_template;
-
+  tree pushed_scope;
+  
   if (DECL_USE_TEMPLATE (function)
       && !(TREE_CODE (function) == TEMPLATE_DECL
           && DECL_TEMPLATE_SPECIALIZATION (function))
@@ -579,16 +580,18 @@ check_classfn (tree ctype, tree function, tree template_parms)
   /* OK, is this a definition of a member template?  */
   is_template = (template_parms != NULL_TREE);
 
+  /* We must enter the scope here, because conversion operators are
+     named by target type, and type equivalence relies on typenames
+     resolving within the scope of CTYPE.  */
+  pushed_scope = push_scope (ctype);
   ix = class_method_index_for_fn (complete_type (ctype), function);
   if (ix >= 0)
     {
       VEC(tree,gc) *methods = CLASSTYPE_METHOD_VEC (ctype);
       tree fndecls, fndecl = 0;
       bool is_conv_op;
-      tree pushed_scope;
       const char *format = NULL;
 
-      pushed_scope = push_scope (ctype);
       for (fndecls = VEC_index (tree, methods, ix);
           fndecls; fndecls = OVL_NEXT (fndecls))
        {
@@ -627,10 +630,13 @@ check_classfn (tree ctype, tree function, tree template_parms)
                      == DECL_TI_TEMPLATE (fndecl))))
            break;
        }
-      if (pushed_scope)
-       pop_scope (pushed_scope);
       if (fndecls)
-       return OVL_CURRENT (fndecls);
+       {
+         if (pushed_scope)
+           pop_scope (pushed_scope);
+         return OVL_CURRENT (fndecls);
+       }
+      
       error ("prototype for %q#D does not match any in class %qT",
             function, ctype);
       is_conv_op = DECL_CONV_FN_P (fndecl);
@@ -678,6 +684,9 @@ check_classfn (tree ctype, tree function, tree template_parms)
      properly within the class.  */
   if (COMPLETE_TYPE_P (ctype))
     add_method (ctype, function, NULL_TREE);
+  
+  if (pushed_scope)
+    pop_scope (pushed_scope);
   return NULL_TREE;
 }
 
@@ -696,14 +705,6 @@ note_vague_linkage_fn (tree decl)
     }
 }
 
-/* Like note_vague_linkage_fn but for variables.  */
-
-static void
-note_vague_linkage_var (tree var)
-{
-  VEC_safe_push (tree, gc, pending_statics, var);
-}
-
 /* We have just processed the DECL, which is a static data member.
    The other parameters are as for cp_finish_decl.  */
 
@@ -719,8 +720,8 @@ finish_static_data_member_decl (tree decl,
      TREE_CHAIN of our decl.  Instead, we modify cp_finish_decl to do
      the right thing, namely, to put this decl out straight away.  */
 
-  if (! processing_template_decl && TREE_PUBLIC (decl))
-    note_vague_linkage_var (decl);
+  if (! processing_template_decl)
+    VEC_safe_push (tree, gc, pending_statics, decl);
 
   if (LOCAL_CLASS_P (current_class_type))
     pedwarn ("local class %q#T shall not have static data member %q#D",
@@ -764,16 +765,6 @@ grokfield (const cp_declarator *declarator,
   const char *asmspec = 0;
   int flags = LOOKUP_ONLYCONVERTING;
 
-  if (!declspecs->any_specifiers_p
-      && declarator->kind == cdk_id
-      && declarator->u.id.qualifying_scope
-      && TYPE_P (declarator->u.id.qualifying_scope)
-      && IS_AGGR_TYPE (declarator->u.id.qualifying_scope)
-      && TREE_CODE (declarator->u.id.unqualified_name) == IDENTIFIER_NODE)
-    /* Access declaration */
-    return do_class_using_decl (declarator->u.id.qualifying_scope,
-                               declarator->u.id.unqualified_name);
-
   if (init
       && TREE_CODE (init) == TREE_LIST
       && TREE_VALUE (init) == error_mark_node
@@ -951,6 +942,14 @@ grokbitfield (const cp_declarator *declarator,
   if (TREE_CODE (value) == VOID_TYPE)
     return void_type_node;
 
+  if (!INTEGRAL_TYPE_P (TREE_TYPE (value))
+      && (POINTER_TYPE_P (value)
+          || !dependent_type_p (TREE_TYPE (value))))
+    {
+      error ("bit-field %qD with non-integral type", value);
+      return error_mark_node;
+    }
+
   if (TREE_CODE (value) == TYPE_DECL)
     {
       error ("cannot declare %qD to be a bit-field type", value);
@@ -997,7 +996,8 @@ grokbitfield (const cp_declarator *declarator,
 void
 cplus_decl_attributes (tree *decl, tree attributes, int flags)
 {
-  if (*decl == NULL_TREE || *decl == void_type_node)
+  if (*decl == NULL_TREE || *decl == void_type_node
+      || *decl == error_mark_node)
     return;
 
   if (TREE_CODE (*decl) == TEMPLATE_DECL)
@@ -1395,7 +1395,7 @@ import_export_class (tree ctype)
   if (MULTIPLE_SYMBOL_SPACES && import_export == -1)
     import_export = 0;
 
-  /* Allow backends the chance to overrule the decision.  */
+  /* Allow back ends the chance to overrule the decision.  */
   if (targetm.cxx.import_export_class)
     import_export = targetm.cxx.import_export_class (ctype, import_export);
 
@@ -1411,7 +1411,7 @@ import_export_class (tree ctype)
 static bool
 var_finalized_p (tree var)
 {
-  return cgraph_varpool_node (var)->finalized;
+  return varpool_node (var)->finalized;
 }
 
 /* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason,
@@ -1447,7 +1447,7 @@ decl_needed_p (tree decl)
      emitted; they may be referred to from other object files.  */
   if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
     return true;
-  /* If this entity was used, let the back-end see it; it will decide
+  /* If this entity was used, let the back end see it; it will decide
      whether or not to emit it into the object file.  */
   if (TREE_USED (decl)
       || (DECL_ASSEMBLER_NAME_SET_P (decl)
@@ -1536,7 +1536,7 @@ maybe_emit_vtables (tree ctype)
 /* A special return value from type_visibility meaning internal
    linkage.  */
 
-enum { VISIBILITY_STATIC = VISIBILITY_INTERNAL+1 };
+enum { VISIBILITY_ANON = VISIBILITY_INTERNAL+1 };
 
 /* walk_tree helper function for type_visibility.  */
 
@@ -1552,7 +1552,7 @@ min_vis_r (tree *tp, int *walk_subtrees, void *data)
     {
       if (!TREE_PUBLIC (TYPE_MAIN_DECL (*tp)))
        {
-         *vis_p = VISIBILITY_STATIC;
+         *vis_p = VISIBILITY_ANON;
          return *tp;
        }
       else if (CLASSTYPE_VISIBILITY (*tp) > *vis_p)
@@ -1572,29 +1572,28 @@ type_visibility (tree type)
   return vis;
 }
 
-/* Limit the visibility of DECL to VISIBILITY.  SPECIFIED is true if the
-   constraint comes from an attribute or pragma; REASON is the source of
-   the constraint.  */
+/* Limit the visibility of DECL to VISIBILITY, if not explicitly
+   specified (or if VISIBILITY is static).  */
 
 static bool
-constrain_visibility (tree decl, int visibility, bool specified,
-                     const char *reason)
+constrain_visibility (tree decl, int visibility)
 {
-  if (visibility == VISIBILITY_STATIC)
+  if (visibility == VISIBILITY_ANON)
     {
-      TREE_PUBLIC (decl) = 0;
-      DECL_INTERFACE_KNOWN (decl) = 1;
-      if (DECL_LANG_SPECIFIC (decl))
-       DECL_NOT_REALLY_EXTERN (decl) = 1;
+      /* extern "C" declarations aren't affected by the anonymous
+        namespace.  */
+      if (!DECL_EXTERN_C_P (decl))
+       {
+         TREE_PUBLIC (decl) = 0;
+         DECL_INTERFACE_KNOWN (decl) = 1;
+         if (DECL_LANG_SPECIFIC (decl))
+           DECL_NOT_REALLY_EXTERN (decl) = 1;
+       }
     }
-  else if (visibility > DECL_VISIBILITY (decl))
+  else if (visibility > DECL_VISIBILITY (decl)
+          && !DECL_VISIBILITY_SPECIFIED (decl))
     {
-      if (lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)))
-       warning (OPT_Wattributes, "%q+D: visibility attribute requests "
-                "greater visibility than its %s allows", decl, reason);
       DECL_VISIBILITY (decl) = visibility;
-      if (!DECL_VISIBILITY_SPECIFIED (decl))
-       DECL_VISIBILITY_SPECIFIED (decl) = specified;
       return true;
     }
   return false;
@@ -1627,13 +1626,13 @@ constrain_visibility_for_template (tree decl, tree targs)
              || TREE_CODE (arg) == FUNCTION_DECL)
            {
              if (! TREE_PUBLIC (arg))
-               vis = VISIBILITY_STATIC;
+               vis = VISIBILITY_ANON;
              else
                vis = DECL_VISIBILITY (arg);
            }
        }
       if (vis)
-       constrain_visibility (decl, vis, false, "template parameter");
+       constrain_visibility (decl, vis);
     }
 }
 
@@ -1735,8 +1734,7 @@ determine_visibility (tree decl)
        {
          /* tinfo visibility is based on the type it's for.  */
          constrain_visibility
-           (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))),
-            false, "type");
+           (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))));
        }
       else if (use_template)
        /* Template instantiations and specializations get visibility based
@@ -1752,43 +1750,46 @@ determine_visibility (tree decl)
 
   if (use_template)
     {
+      /* If the specialization doesn't specify visibility, use the
+        visibility from the template.  */
       tree tinfo = (TREE_CODE (decl) == TYPE_DECL
                    ? TYPE_TEMPLATE_INFO (TREE_TYPE (decl))
                    : DECL_TEMPLATE_INFO (decl));
       tree args = TI_ARGS (tinfo);
-      int depth = TMPL_ARGS_DEPTH (args);
-
-      /* If the template has explicit visibility and the specialization
-        doesn't, use the visibility from the template.  */
-      if (!DECL_VISIBILITY_SPECIFIED (decl))
+      
+      if (args != error_mark_node)
        {
+         int depth = TMPL_ARGS_DEPTH (args);
          tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo));
-         DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern);
-       }
 
-      /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */
-      if (args && depth > template_class_depth (class_type))
-       /* Don't let it have more visibility than its template type
-          arguments.  */
-       constrain_visibility_for_template (decl, args);
+         if (!DECL_VISIBILITY_SPECIFIED (decl))
+           {
+             DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern);
+             DECL_VISIBILITY_SPECIFIED (decl)
+               = DECL_VISIBILITY_SPECIFIED (pattern);
+           }
+
+         /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */
+         if (args && depth > template_class_depth (class_type))
+           /* Limit visibility based on its template arguments.  */
+           constrain_visibility_for_template (decl, args);
+       }
     }
-  
+
   if (class_type)
     determine_visibility_from_class (decl, class_type);
 
-  /* Don't let it have more visibility than its type.  */
-  if (TREE_CODE (decl) != TYPE_DECL)
-    if (constrain_visibility (decl, type_visibility (TREE_TYPE (decl)),
-                             false, "type"))
-      warning (OPT_Wattributes, "\
-%q+D declared with greater visibility than its type",
-              decl);
-
   if (decl_anon_ns_mem_p (decl))
     /* Names in an anonymous namespace get internal linkage.
        This might change once we implement export.  */
-    constrain_visibility (decl, VISIBILITY_STATIC,
-                         false, "namespace");
+    constrain_visibility (decl, VISIBILITY_ANON);
+  else if (TREE_CODE (decl) != TYPE_DECL)
+    {
+      /* Propagate anonymity from type to decl.  */
+      int tvis = type_visibility (TREE_TYPE (decl));
+      if (tvis == VISIBILITY_ANON)
+       constrain_visibility (decl, tvis);
+    }
 }
 
 /* By default, static data members and function members receive
@@ -1804,13 +1805,17 @@ determine_visibility_from_class (tree decl, tree class_type)
       && !processing_template_decl
       && ! DECL_VISIBILITY_SPECIFIED (decl)
       && TREE_CODE (decl) == FUNCTION_DECL
-      && DECL_DECLARED_INLINE_P (decl))
+      && DECL_DECLARED_INLINE_P (decl)
+      && (! DECL_LANG_SPECIFIC (decl)
+         || ! DECL_EXPLICIT_INSTANTIATION (decl)))
     DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
-
-  /* The decl can't have more visibility than its class.  */
-  constrain_visibility (decl, CLASSTYPE_VISIBILITY (class_type),
-                       CLASSTYPE_VISIBILITY_SPECIFIED (class_type),
-                       "class");
+  else if (!DECL_VISIBILITY_SPECIFIED (decl))
+    {
+      /* Default to the class visibility.  */
+      DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
+      DECL_VISIBILITY_SPECIFIED (decl)
+       = CLASSTYPE_VISIBILITY_SPECIFIED (class_type);
+    }
 
   /* Give the target a chance to override the visibility associated
      with DECL.  */
@@ -1823,8 +1828,8 @@ determine_visibility_from_class (tree decl, tree class_type)
              && !DECL_CONSTRUCTION_VTABLE_P (decl)))
       && TREE_PUBLIC (decl)
       && !DECL_REALLY_EXTERN (decl)
-      && DECL_VISIBILITY_SPECIFIED (decl)
-      && (!class_type || !CLASSTYPE_VISIBILITY_SPECIFIED (class_type)))
+      && !DECL_VISIBILITY_SPECIFIED (decl)
+      && !CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
     targetm.cxx.determine_class_data_visibility (decl);
 }
 
@@ -1834,25 +1839,61 @@ determine_visibility_from_class (tree decl, tree class_type)
 void
 constrain_class_visibility (tree type)
 {
-  tree decl = TYPE_MAIN_DECL (type);
-  tree binfo = TYPE_BINFO (type);
+  tree binfo;
   tree t;
   int i;
 
+  int vis = type_visibility (type);
+
+  if (vis == VISIBILITY_ANON
+      || DECL_IN_SYSTEM_HEADER (TYPE_MAIN_DECL (type)))
+    return;
+
+  /* Don't warn about visibility if the class has explicit visibility.  */
+  if (CLASSTYPE_VISIBILITY_SPECIFIED (type))
+    vis = VISIBILITY_INTERNAL;
+
   for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
-    if (TREE_CODE (t) == FIELD_DECL)
-      if (constrain_visibility (decl, type_visibility (TREE_TYPE (t)),
-                               false, "field type"))
-       warning (OPT_Wattributes, "\
+    if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node)
+      {
+       tree ftype = strip_pointer_or_array_types (TREE_TYPE (t));
+       int subvis = type_visibility (ftype);
+
+       if (subvis == VISIBILITY_ANON)
+         {
+           if (strcmp (main_input_filename,
+                       DECL_SOURCE_FILE (TYPE_MAIN_DECL (ftype))))
+             warning (0, "\
+%qT has a field %qD whose type uses the anonymous namespace",
+                      type, t);
+         }
+       else if (IS_AGGR_TYPE (ftype)
+                && vis < VISIBILITY_HIDDEN
+                && subvis >= VISIBILITY_HIDDEN)
+         warning (OPT_Wattributes, "\
 %qT declared with greater visibility than the type of its field %qD",
-                type, t);
+                  type, t);
+      }
 
+  binfo = TYPE_BINFO (type);
   for (i = 0; BINFO_BASE_ITERATE (binfo, i, t); ++i)
-    if (constrain_visibility (decl, type_visibility (TREE_TYPE (t)),
-                             false, "base type"))
-      warning (OPT_Wattributes, "\
+    {
+      int subvis = type_visibility (TREE_TYPE (t));
+
+      if (subvis == VISIBILITY_ANON)
+        {
+         if (strcmp (main_input_filename,
+                     DECL_SOURCE_FILE (TYPE_MAIN_DECL (TREE_TYPE (t)))))
+           warning (0, "\
+%qT has a base %qT whose type uses the anonymous namespace",
+                    type, TREE_TYPE (t));
+       }
+      else if (vis < VISIBILITY_HIDDEN
+              && subvis >= VISIBILITY_HIDDEN)
+       warning (OPT_Wattributes, "\
 %qT declared with greater visibility than its base %qT",
-              type, TREE_TYPE (t));
+                type, TREE_TYPE (t));
+    }
 }
 
 /* DECL is a FUNCTION_DECL or VAR_DECL.  If the object file linkage
@@ -2149,10 +2190,7 @@ build_cleanup (tree decl)
   if (TREE_CODE (type) == ARRAY_TYPE)
     temp = decl;
   else
-    {
-      cxx_mark_addressable (decl);
-      temp = build1 (ADDR_EXPR, build_pointer_type (type), decl);
-    }
+    temp = build_address (decl);
   temp = build_delete (TREE_TYPE (temp), temp,
                       sfk_complete_destructor,
                       LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
@@ -2287,14 +2325,12 @@ start_objects (int method_type, int initp)
     sprintf (type, "%c", method_type);
 
   fndecl = build_lang_decl (FUNCTION_DECL,
-                           get_file_function_name_long (type),
+                           get_file_function_name (type),
                            build_function_type (void_type_node,
                                                 void_list_node));
   start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED);
 
-  /* It can be a static function as long as collect2 does not have
-     to scan the object file to find its ctor/dtor routine.  */
-  TREE_PUBLIC (current_function_decl) = ! targetm.have_ctors_dtors;
+  TREE_PUBLIC (current_function_decl) = 0;
 
   /* Mark this declaration as used to avoid spurious warnings.  */
   TREE_USED (current_function_decl) = 1;
@@ -2308,13 +2344,6 @@ start_objects (int method_type, int initp)
 
   body = begin_compound_stmt (BCS_FN_BODY);
 
-  /* We cannot allow these functions to be elided, even if they do not
-     have external linkage.  And, there's no point in deferring
-     compilation of these functions; they're all going to have to be
-     out anyhow.  */
-  DECL_INLINE (current_function_decl) = 0;
-  DECL_UNINLINABLE (current_function_decl) = 1;
-
   return body;
 }
 
@@ -2329,23 +2358,19 @@ finish_objects (int method_type, int initp, tree body)
   /* Finish up.  */
   finish_compound_stmt (body);
   fn = finish_function (0);
-  expand_or_defer_fn (fn);
-
-  /* When only doing semantic analysis, and no RTL generation, we
-     can't call functions that directly emit assembly code; there is
-     no assembly file in which to put the code.  */
-  if (flag_syntax_only)
-    return;
 
-  if (targetm.have_ctors_dtors)
+  if (method_type == 'I')
     {
-      rtx fnsym = XEXP (DECL_RTL (fn), 0);
-      cgraph_mark_needed_node (cgraph_node (fn));
-      if (method_type == 'I')
-       (* targetm.asm_out.constructor) (fnsym, initp);
-      else
-       (* targetm.asm_out.destructor) (fnsym, initp);
+      DECL_STATIC_CONSTRUCTOR (fn) = 1;
+      decl_init_priority_insert (fn, initp);
+    }
+  else
+    {
+      DECL_STATIC_DESTRUCTOR (fn) = 1;
+      decl_fini_priority_insert (fn, initp);
     }
+
+  expand_or_defer_fn (fn);
 }
 
 /* The names of the parameters to the function created to handle
@@ -2412,6 +2437,7 @@ start_static_storage_duration_function (unsigned count)
                               type);
   TREE_PUBLIC (ssdf_decl) = 0;
   DECL_ARTIFICIAL (ssdf_decl) = 1;
+  DECL_INLINE (ssdf_decl) = 1;
 
   /* Put this function in the list of functions to be called from the
      static constructors and destructors.  */
@@ -2465,11 +2491,6 @@ start_static_storage_duration_function (unsigned count)
   /* Set up the scope of the outermost block in the function.  */
   body = begin_compound_stmt (BCS_FN_BODY);
 
-  /* This function must not be deferred because we are depending on
-     its compilation to tell us what is TREE_SYMBOL_REFERENCED.  */
-  DECL_INLINE (ssdf_decl) = 0;
-  DECL_UNINLINABLE (ssdf_decl) = 1;
-
   return body;
 }
 
@@ -2792,7 +2813,7 @@ write_out_vars (tree vars)
 }
 
 /* Generate a static constructor (if CONSTRUCTOR_P) or destructor
-   (otherwise) that will initialize all gobal objects with static
+   (otherwise) that will initialize all global objects with static
    storage duration having the indicated PRIORITY.  */
 
 static void
@@ -2826,7 +2847,7 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
       && constructor_p && objc_static_init_needed_p ())
     {
       body = start_objects (function_key, priority);
-      static_ctors = objc_generate_static_init_call (static_ctors);
+      objc_generate_static_init_call (NULL_TREE);
     }
 
   /* Call the static storage duration function with appropriate
@@ -2849,29 +2870,6 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
        }
     }
 
-  /* If we're generating code for the DEFAULT_INIT_PRIORITY, throw in
-     calls to any functions marked with attributes indicating that
-     they should be called at initialization- or destruction-time.  */
-  if (priority == DEFAULT_INIT_PRIORITY)
-    {
-      tree fns;
-
-      for (fns = constructor_p ? static_ctors : static_dtors;
-          fns;
-          fns = TREE_CHAIN (fns))
-       {
-         fndecl = TREE_VALUE (fns);
-
-         /* Calls to pure/const functions will expand to nothing.  */
-         if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
-           {
-             if (! body)
-               body = start_objects (function_key, priority);
-             finish_expr_stmt (build_function_call (fndecl, NULL_TREE));
-           }
-       }
-    }
-
   /* Close out the function.  */
   if (body)
     finish_objects (function_key, priority, body);
@@ -2889,11 +2887,9 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
 
   /* Generate the functions themselves, but only if they are really
      needed.  */
-  if (pi->initializations_p
-      || (priority == DEFAULT_INIT_PRIORITY && static_ctors))
+  if (pi->initializations_p)
     generate_ctor_or_dtor_function (/*constructor_p=*/true, priority, locus);
-  if (pi->destructions_p
-      || (priority == DEFAULT_INIT_PRIORITY && static_dtors))
+  if (pi->destructions_p)
     generate_ctor_or_dtor_function (/*constructor_p=*/false, priority, locus);
 
   /* Keep iterating.  */
@@ -2901,7 +2897,7 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
 }
 
 /* Called via LANGHOOK_CALLGRAPH_ANALYZE_EXPR.  It is supposed to mark
-   decls referenced from frontend specific constructs; it will be called
+   decls referenced from front-end specific constructs; it will be called
    only for language-specific tree nodes.
 
    Here we must deal with member pointers.  */
@@ -2990,13 +2986,13 @@ build_java_method_aliases (void)
     }
 }
 
-/* This routine is called from the last rule in yyparse ().
+/* This routine is called at the end of compilation.
    Its job is to create all the code needed to initialize and
    destroy the global aggregates.  We do the destruction
    first, since that way we only need to reverse the decls once.  */
 
 void
-cp_finish_file (void)
+cp_write_global_declarations (void)
 {
   tree vars;
   bool reconsider;
@@ -3114,7 +3110,7 @@ cp_finish_file (void)
             through the loop.  That's because we need to know which
             vtables have been referenced, and TREE_SYMBOL_REFERENCED
             isn't computed until a function is finished, and written
-            out.  That's a deficiency in the back-end.  When this is
+            out.  That's a deficiency in the back end.  When this is
             fixed, these initialization functions could all become
             inline, with resulting performance improvements.  */
          tree ssdf_body;
@@ -3189,7 +3185,7 @@ cp_finish_file (void)
          if (!DECL_SAVED_TREE (decl))
            continue;
 
-         /* We lie to the back-end, pretending that some functions
+         /* We lie to the back end, pretending that some functions
             are not defined when they really are.  This keeps these
             functions from being put out unnecessarily.  But, we must
             stop lying when the functions are referenced, or if they
@@ -3288,17 +3284,11 @@ cp_finish_file (void)
     splay_tree_foreach (priority_info_map,
                        generate_ctor_and_dtor_functions_for_priority,
                        /*data=*/&locus);
-  else
-    {
-      /* If we have a ctor or this is obj-c++ and we need a static init,
-        call generate_ctor_or_dtor_function.  */
-      if (static_ctors || (c_dialect_objc () && objc_static_init_needed_p ()))
-       generate_ctor_or_dtor_function (/*constructor_p=*/true,
-                                       DEFAULT_INIT_PRIORITY, &locus);
-      if (static_dtors)
-       generate_ctor_or_dtor_function (/*constructor_p=*/false,
-                                       DEFAULT_INIT_PRIORITY, &locus);
-    }
+  else if (c_dialect_objc () && objc_static_init_needed_p ())
+    /* If this is obj-c++ and we need a static init, call
+       generate_ctor_or_dtor_function.  */
+    generate_ctor_or_dtor_function (/*constructor_p=*/true,
+                                   DEFAULT_INIT_PRIORITY, &locus);
 
   /* We're done with the splay-tree now.  */
   if (priority_info_map)
@@ -3380,7 +3370,7 @@ build_offset_ref_call_from_tree (tree fn, tree args)
                  || TREE_CODE (fn) == MEMBER_REF);
       if (type_dependent_expression_p (fn)
          || any_type_dependent_arguments_p (args))
-       return build_min_nt (CALL_EXPR, fn, args, NULL_TREE);
+       return build_nt_call_list (fn, args);
 
       /* Transform the arguments and add the implicit "this"
         parameter.  That must be done before the FN is transformed
@@ -3410,7 +3400,7 @@ build_offset_ref_call_from_tree (tree fn, tree args)
 
   expr = build_function_call (fn, args);
   if (processing_template_decl && expr != error_mark_node)
-    return build_min_non_dep (CALL_EXPR, expr, orig_fn, orig_args, NULL_TREE);
+    return build_min_non_dep_call_list (expr, orig_fn, orig_args);
   return expr;
 }
 
@@ -3455,6 +3445,8 @@ mark_used (tree decl)
     }
 
   TREE_USED (decl) = 1;
+  if (DECL_CLONED_FUNCTION_P (decl))
+    TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
   /* If we don't need a value, then we don't need to synthesize DECL.  */
   if (skip_evaluation)
     return;