OSDN Git Service

* decl2.c (is_late_template_attribute): Don't defer attribute
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index ac85b44..fa8d28a 100644 (file)
@@ -1,13 +1,13 @@
 /* Process declarations and variables for C++ compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007  Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -16,9 +16,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 
 /* Process declarations and symbol lookup for C++ front end.
@@ -97,11 +96,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
@@ -114,6 +108,9 @@ build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
   tree raises;
   int type_quals;
 
+  if (fntype == error_mark_node || ctype == error_mark_node)
+    return error_mark_node;
+
   type_quals = quals & ~TYPE_QUAL_RESTRICT;
   ctype = cp_build_qualified_type (ctype, type_quals);
   fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
@@ -138,6 +135,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;
 }
 
@@ -442,23 +445,11 @@ 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);
-
-      if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
-       {
-         /* 14.5.2.3 [temp.mem]
-
-            A member function template shall not be virtual.  */
-         error
-           ("invalid use of %<virtual%> in template declaration of %q#D",
-            decl);
-         DECL_VIRTUAL_P (decl) = 0;
-       }
+      /* 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)));
 
       /* The debug-information generating code doesn't know what to do
         with member templates.  */
@@ -473,8 +464,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);
@@ -530,8 +524,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;
        }
     }
@@ -545,15 +540,16 @@ check_java_method (tree method)
    TEMPLATE_DECL, it can be NULL since the parameters can be extracted
    from the declaration. If the function is not a function template, it
    must be NULL.
-   It returns the original declaration for the function, or NULL_TREE
-   if no declaration was found (and an error was emitted).  */
+   It returns the original declaration for the function, NULL_TREE if
+   no declaration was found, error_mark_node if an error was emitted.  */
 
 tree
 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))
@@ -583,16 +579,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))
        {
@@ -631,10 +629,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);
@@ -676,13 +677,9 @@ check_classfn (tree ctype, tree function, tree template_parms)
     error ("no %q#D member function declared in class %qT",
           function, ctype);
 
-  /* If we did not find the method in the class, add it to avoid
-     spurious errors (unless the CTYPE is not yet defined, in which
-     case we'll only confuse ourselves when the function is declared
-     properly within the class.  */
-  if (COMPLETE_TYPE_P (ctype))
-    add_method (ctype, function, NULL_TREE);
-  return NULL_TREE;
+  if (pushed_scope)
+    pop_scope (pushed_scope);
+  return error_mark_node;
 }
 
 /* DECL is a function with vague linkage.  Remember it so that at the
@@ -700,36 +697,23 @@ 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.  */
 
 void
-finish_static_data_member_decl (tree decl, 
+finish_static_data_member_decl (tree decl,
                                tree init, bool init_const_expr_p,
                                tree asmspec_tree,
                                int flags)
 {
-  gcc_assert (TREE_PUBLIC (decl));
-
   DECL_CONTEXT (decl) = current_class_type;
 
   /* We cannot call pushdecl here, because that would fill in the
      TREE_CHAIN of our decl.  Instead, we modify cp_finish_decl to do
      the right thing, namely, to put this decl out straight away.  */
-  /* current_class_type can be NULL_TREE in case of error.  */
-  if (!asmspec_tree && current_class_type)
-    DECL_INITIAL (decl) = error_mark_node;
 
   if (! processing_template_decl)
-    note_vague_linkage_var (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",
@@ -760,7 +744,7 @@ finish_static_data_member_decl (tree decl,
 
 /* DECLARATOR and DECLSPECS correspond to a class member.  The other
    parameters are as for cp_finish_decl.  Return the DECL for the
-   class member declared.  */ 
+   class member declared.  */
 
 tree
 grokfield (const cp_declarator *declarator,
@@ -773,14 +757,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
-      && 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
@@ -824,16 +800,7 @@ grokfield (const cp_declarator *declarator,
        value = push_template_decl (value);
 
       if (attrlist)
-       {
-         /* Avoid storing attributes in template parameters:
-            tsubst is not ready to handle them.  */
-         tree type = TREE_TYPE (value);
-         if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
-             || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
-           sorry ("applying attributes to template parameters is not implemented");
-         else
-           cplus_decl_attributes (&value, attrlist, 0);
-       }
+       cplus_decl_attributes (&value, attrlist, 0);
 
       return value;
     }
@@ -844,7 +811,7 @@ grokfield (const cp_declarator *declarator,
       return void_type_node;
     }
 
-  if (asmspec_tree)
+  if (asmspec_tree && asmspec_tree != error_mark_node)
     asmspec = TREE_STRING_POINTER (asmspec_tree);
 
   if (init)
@@ -914,7 +881,7 @@ grokfield (const cp_declarator *declarator,
        error ("%<asm%> specifiers are not permitted on non-static data members");
       if (DECL_INITIAL (value) == error_mark_node)
        init = error_mark_node;
-      cp_finish_decl (value, init, /*init_const_expr_p=*/false, 
+      cp_finish_decl (value, init, /*init_const_expr_p=*/false,
                      NULL_TREE, flags);
       DECL_INITIAL (value) = init;
       DECL_IN_AGGR_P (value) = 1;
@@ -924,7 +891,9 @@ grokfield (const cp_declarator *declarator,
       if (asmspec)
        set_user_assembler_name (value, asmspec);
 
-      cp_finish_decl (value, init, /*init_const_expr_p=*/false, 
+      cp_finish_decl (value,
+                     /*init=*/NULL_TREE,
+                     /*init_const_expr_p=*/false,
                      asmspec_tree, flags);
 
       /* Pass friends back this way.  */
@@ -949,12 +918,21 @@ grokbitfield (const cp_declarator *declarator,
 {
   tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL);
 
-  if (! value) return NULL_TREE; /* friends went bad.  */
+  if (value == error_mark_node) 
+    return NULL_TREE; /* friends went bad.  */
 
   /* Pass friendly classes back.  */
   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);
@@ -998,12 +976,142 @@ grokbitfield (const cp_declarator *declarator,
 }
 
 \f
+/* Returns true iff ATTR is an attribute which needs to be applied at
+   instantiation time rather than template definition time.  */
+
+static bool
+is_late_template_attribute (tree attr, tree decl)
+{
+  tree name = TREE_PURPOSE (attr);
+  tree args = TREE_VALUE (attr);
+  const struct attribute_spec *spec = lookup_attribute_spec (name);
+  tree arg;
+
+  if (!spec)
+    /* Unknown attribute.  */
+    return false;
+
+  /* If any of the arguments are dependent expressions, we can't evaluate
+     the attribute until instantiation time.  */
+  for (arg = args; arg; arg = TREE_CHAIN (arg))
+    {
+      tree t = TREE_VALUE (arg);
+      if (value_dependent_expression_p (t)
+         || type_dependent_expression_p (t))
+       return true;
+    }
+
+  if (TREE_CODE (decl) == TYPE_DECL
+      || TYPE_P (decl)
+      || spec->type_required)
+    {
+      tree type = TYPE_P (decl) ? decl : TREE_TYPE (decl);
+
+      /* We can't apply any attributes to a completely unknown type until
+        instantiation time.  */
+      enum tree_code code = TREE_CODE (type);
+      if (code == TEMPLATE_TYPE_PARM
+         || code == BOUND_TEMPLATE_TEMPLATE_PARM
+         || code == TYPENAME_TYPE)
+       return true;
+      /* Also defer most attributes on dependent types.  This is not
+        necessary in all cases, but is the better default.  */
+      else if (dependent_type_p (type)
+              /* But attribute visibility specifically works on
+                 templates.  */
+              && !is_attribute_p ("visibility", name))
+       return true;
+      else
+       return false;
+    }
+  else
+    return false;
+}
+
+/* ATTR_P is a list of attributes.  Remove any attributes which need to be
+   applied at instantiation time and return them.  If IS_DEPENDENT is true,
+   the declaration itself is dependent, so all attributes should be applied
+   at instantiation time.  */
+
+static tree
+splice_template_attributes (tree *attr_p, tree decl)
+{
+  tree *p = attr_p;
+  tree late_attrs = NULL_TREE;
+  tree *q = &late_attrs;
+
+  if (!p)
+    return NULL_TREE;
+
+  for (; *p; )
+    {
+      if (is_late_template_attribute (*p, decl))
+       {
+         ATTR_IS_DEPENDENT (*p) = 1;
+         *q = *p;
+         *p = TREE_CHAIN (*p);
+         q = &TREE_CHAIN (*q);
+         *q = NULL_TREE;
+       }
+      else
+       p = &TREE_CHAIN (*p);
+    }
+
+  return late_attrs;
+}
+
+/* Remove any late attributes from the list in ATTR_P and attach them to
+   DECL_P.  */
+
+static void
+save_template_attributes (tree *attr_p, tree *decl_p)
+{
+  tree late_attrs = splice_template_attributes (attr_p, *decl_p);
+  tree *q;
+
+  if (!late_attrs)
+    return;
+
+  /* Give this type a name so we know to look it up again at instantiation
+     time.  */
+  if (TREE_CODE (*decl_p) == TYPE_DECL
+      && DECL_ORIGINAL_TYPE (*decl_p) == NULL_TREE)
+    {
+      tree oldt = TREE_TYPE (*decl_p);
+      tree newt = build_variant_type_copy (oldt);
+      DECL_ORIGINAL_TYPE (*decl_p) = oldt;
+      TREE_TYPE (*decl_p) = newt;
+      TYPE_NAME (newt) = *decl_p;
+      TREE_USED (newt) = TREE_USED (*decl_p);
+    }
+
+  if (DECL_P (*decl_p))
+    q = &DECL_ATTRIBUTES (*decl_p);
+  else
+    q = &TYPE_ATTRIBUTES (*decl_p);
+
+  if (*q)
+    q = &TREE_CHAIN (tree_last (*q));
+  *q = late_attrs;
+}
+
+/* Like decl_attributes, but handle C++ complexity.  */
+
 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
+      || attributes == NULL_TREE)
     return;
 
+  if (processing_template_decl)
+    {
+      save_template_attributes (&attributes, decl);
+      if (attributes == NULL_TREE)
+       return;
+    }
+
   if (TREE_CODE (*decl) == TEMPLATE_DECL)
     decl = &DECL_TEMPLATE_RESULT (*decl);
 
@@ -1061,6 +1169,7 @@ build_anon_union_vars (tree type, tree object)
          tree base;
 
          decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
+         DECL_ANON_UNION_VAR_P (decl) = 1;
 
          base = get_base_address (object);
          TREE_PUBLIC (decl) = TREE_PUBLIC (base);
@@ -1114,6 +1223,8 @@ finish_anon_union (tree anon_union_decl)
     }
 
   main_decl = build_anon_union_vars (type, anon_union_decl);
+  if (main_decl == error_mark_node)
+    return;
   if (main_decl == NULL_TREE)
     {
       warning (0, "anonymous union with no members");
@@ -1155,15 +1266,33 @@ coerce_new_type (tree type)
       error ("%<operator new%> must return type %qT", ptr_type_node);
     }
 
-  if (!args || args == void_list_node
-      || !same_type_p (TREE_VALUE (args), size_type_node))
+  if (args && args != void_list_node)
     {
-      e = 2;
-      if (args && args != void_list_node)
-       args = TREE_CHAIN (args);
-      pedwarn ("%<operator new%> takes type %<size_t%> (%qT) "
-              "as first parameter", size_type_node);
+      if (TREE_PURPOSE (args))
+       {
+         /* [basic.stc.dynamic.allocation]
+            
+            The first parameter shall not have an associated default
+            argument.  */
+         error ("the first parameter of %<operator new%> cannot "
+                "have a default argument");
+         /* Throw away the default argument.  */
+         TREE_PURPOSE (args) = NULL_TREE;
+       }
+
+      if (!same_type_p (TREE_VALUE (args), size_type_node))
+       {
+         e = 2;
+         args = TREE_CHAIN (args);
+       }
     }
+  else
+    e = 2;
+
+  if (e == 2)
+    pedwarn ("%<operator new%> takes type %<size_t%> (%qT) "
+            "as first parameter", size_type_node);
+
   switch (e)
   {
     case 2:
@@ -1218,6 +1347,9 @@ coerce_delete_type (tree type)
   return type;
 }
 \f
+/* DECL is a VAR_DECL for a vtable: walk through the entries in the vtable
+   and mark them as needed.  */
+
 static void
 mark_vtable_entries (tree decl)
 {
@@ -1397,7 +1529,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);
 
@@ -1413,7 +1545,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,
@@ -1449,7 +1581,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)
@@ -1535,6 +1667,110 @@ maybe_emit_vtables (tree ctype)
   return true;
 }
 
+/* A special return value from type_visibility meaning internal
+   linkage.  */
+
+enum { VISIBILITY_ANON = VISIBILITY_INTERNAL+1 };
+
+/* walk_tree helper function for type_visibility.  */
+
+static tree
+min_vis_r (tree *tp, int *walk_subtrees, void *data)
+{
+  int *vis_p = (int *)data;
+  if (! TYPE_P (*tp))
+    {
+      *walk_subtrees = 0;
+    }
+  else if (CLASS_TYPE_P (*tp))
+    {
+      if (!TREE_PUBLIC (TYPE_MAIN_DECL (*tp)))
+       {
+         *vis_p = VISIBILITY_ANON;
+         return *tp;
+       }
+      else if (CLASSTYPE_VISIBILITY (*tp) > *vis_p)
+       *vis_p = CLASSTYPE_VISIBILITY (*tp);
+    }
+  return NULL;
+}
+
+/* Returns the visibility of TYPE, which is the minimum visibility of its
+   component types.  */
+
+static int
+type_visibility (tree type)
+{
+  int vis = VISIBILITY_DEFAULT;
+  cp_walk_tree_without_duplicates (&type, min_vis_r, &vis);
+  return vis;
+}
+
+/* Limit the visibility of DECL to VISIBILITY, if not explicitly
+   specified (or if VISIBILITY is static).  */
+
+static bool
+constrain_visibility (tree decl, int visibility)
+{
+  if (visibility == VISIBILITY_ANON)
+    {
+      /* extern "C" declarations aren't affected by the anonymous
+        namespace.  */
+      if (!DECL_EXTERN_C_P (decl))
+       {
+         TREE_PUBLIC (decl) = 0;
+         DECL_ONE_ONLY (decl) = 0;
+         DECL_INTERFACE_KNOWN (decl) = 1;
+         if (DECL_LANG_SPECIFIC (decl))
+           DECL_NOT_REALLY_EXTERN (decl) = 1;
+       }
+    }
+  else if (visibility > DECL_VISIBILITY (decl)
+          && !DECL_VISIBILITY_SPECIFIED (decl))
+    {
+      DECL_VISIBILITY (decl) = visibility;
+      return true;
+    }
+  return false;
+}
+
+/* Constrain the visibility of DECL based on the visibility of its template
+   arguments.  */
+
+static void
+constrain_visibility_for_template (tree decl, tree targs)
+{
+  /* If this is a template instantiation, check the innermost
+     template args for visibility constraints.  The outer template
+     args are covered by the class check.  */
+  tree args = INNERMOST_TEMPLATE_ARGS (targs);
+  int i;
+  for (i = TREE_VEC_LENGTH (args); i > 0; --i)
+    {
+      int vis = 0;
+
+      tree arg = TREE_VEC_ELT (args, i-1);
+      if (TYPE_P (arg))
+       vis = type_visibility (arg);
+      else if (TREE_TYPE (arg) && POINTER_TYPE_P (TREE_TYPE (arg)))
+       {
+         STRIP_NOPS (arg);
+         if (TREE_CODE (arg) == ADDR_EXPR)
+           arg = TREE_OPERAND (arg, 0);
+         if (TREE_CODE (arg) == VAR_DECL
+             || TREE_CODE (arg) == FUNCTION_DECL)
+           {
+             if (! TREE_PUBLIC (arg))
+               vis = VISIBILITY_ANON;
+             else
+               vis = DECL_VISIBILITY (arg);
+           }
+       }
+      if (vis)
+       constrain_visibility (decl, vis);
+    }
+}
+
 /* Like c_determine_visibility, but with additional C++-specific
    behavior.
 
@@ -1546,12 +1782,18 @@ maybe_emit_vtables (tree ctype)
 
    Note that because namespaces have multiple independent definitions,
    namespace visibility is handled elsewhere using the #pragma visibility
-   machinery rather than by decorating the namespace declaration.  */
+   machinery rather than by decorating the namespace declaration.
+
+   The goal is for constraints from the type to give a diagnostic, and
+   other constraints to be applied silently.  */
 
 void
 determine_visibility (tree decl)
 {
-  tree class_type;
+  tree class_type = NULL_TREE;
+  bool use_template;
+
+  /* Remember that all decls get VISIBILITY_DEFAULT when built.  */
 
   /* Only relevant for names with external linkage.  */
   if (!TREE_PUBLIC (decl))
@@ -1562,97 +1804,228 @@ determine_visibility (tree decl)
      maybe_clone_body.  */
   gcc_assert (!DECL_CLONED_FUNCTION_P (decl));
 
-  /* Give the common code a chance to make a determination.  */
-  if (c_determine_visibility (decl))
-    return;
+  if (TREE_CODE (decl) == TYPE_DECL)
+    {
+      if (CLASS_TYPE_P (TREE_TYPE (decl)))
+       use_template = CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl));
+      else if (TYPE_TEMPLATE_INFO (TREE_TYPE (decl)))
+       use_template = 1;
+      else
+       use_template = 0;
+    }
+  else if (DECL_LANG_SPECIFIC (decl))
+    use_template = DECL_USE_TEMPLATE (decl);
+  else
+    use_template = 0;
 
   /* If DECL is a member of a class, visibility specifiers on the
      class can influence the visibility of the DECL.  */
   if (DECL_CLASS_SCOPE_P (decl))
     class_type = DECL_CONTEXT (decl);
-  else if (TREE_CODE (decl) == VAR_DECL
-          && DECL_TINFO_P (decl)
-          && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl))))
-    class_type = TREE_TYPE (DECL_NAME (decl));
   else
     {
+      /* Not a class member.  */
+
       /* Virtual tables have DECL_CONTEXT set to their associated class,
         so they are automatically handled above.  */
       gcc_assert (TREE_CODE (decl) != VAR_DECL
                  || !DECL_VTABLE_OR_VTT_P (decl));
 
-      if (DECL_FUNCTION_SCOPE_P (decl))
+      if (DECL_FUNCTION_SCOPE_P (decl) && ! DECL_VISIBILITY_SPECIFIED (decl))
        {
+         /* Local statics and classes get the visibility of their
+            containing function by default, except that
+            -fvisibility-inlines-hidden doesn't affect them.  */
          tree fn = DECL_CONTEXT (decl);
-         DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
-         DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (fn);
+         if (DECL_VISIBILITY_SPECIFIED (fn) || ! DECL_CLASS_SCOPE_P (fn))
+           {
+             DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
+             DECL_VISIBILITY_SPECIFIED (decl) = 
+               DECL_VISIBILITY_SPECIFIED (fn);
+           }
+         else
+           determine_visibility_from_class (decl, DECL_CONTEXT (fn));
+
+         /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set,
+            but have no TEMPLATE_INFO, so don't try to check it.  */
+         use_template = 0;
+       }
+      else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl)
+              && flag_visibility_ms_compat)
+       {
+         /* Under -fvisibility-ms-compat, types are visible by default,
+            even though their contents aren't.  */
+         tree underlying_type = TREE_TYPE (DECL_NAME (decl));
+         int underlying_vis = type_visibility (underlying_type);
+         if (underlying_vis == VISIBILITY_ANON
+             || CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type))
+           constrain_visibility (decl, underlying_vis);
+         else
+           DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+       }
+      else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl))
+       {
+         /* tinfo visibility is based on the type it's for.  */
+         constrain_visibility
+           (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))));
+       }
+      else if (use_template)
+       /* Template instantiations and specializations get visibility based
+          on their template unless they override it with an attribute.  */;
+      else if (! DECL_VISIBILITY_SPECIFIED (decl))
+       {
+         /* Set default visibility to whatever the user supplied with
+            #pragma GCC visibility or a namespace visibility attribute.  */
+         DECL_VISIBILITY (decl) = default_visibility;
+         DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma;
        }
+    }
 
-      /* Entities not associated with any class just get the
-        visibility specified by their attributes.  */
-      return;
+  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);
+      
+      if (args != error_mark_node)
+       {
+         int depth = TMPL_ARGS_DEPTH (args);
+         tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo));
+
+         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);
+       }
     }
 
-  /* By default, static data members and function members receive
-     the visibility of their containing class.  */
   if (class_type)
+    determine_visibility_from_class (decl, class_type);
+
+  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_ANON);
+  else if (TREE_CODE (decl) != TYPE_DECL)
     {
-      determine_visibility_from_class (decl, class_type);
-
-      /* Give the target a chance to override the visibility associated
-        with DECL.  */
-      if (TREE_CODE (decl) == VAR_DECL
-         && (DECL_TINFO_P (decl)
-             || (DECL_VTABLE_OR_VTT_P (decl)
-                 /* Construction virtual tables are not exported because
-                    they cannot be referred to from other object files;
-                    their name is not standardized by the ABI.  */
-                 && !DECL_CONSTRUCTION_VTABLE_P (decl)))
-         && TREE_PUBLIC (decl)
-         && !DECL_REALLY_EXTERN (decl)
-         && DECL_VISIBILITY_SPECIFIED (decl)
-         && (!class_type || !CLASSTYPE_VISIBILITY_SPECIFIED (class_type)))
-       targetm.cxx.determine_class_data_visibility (decl);
-    }      
+      /* Propagate anonymity from type to decl.  */
+      int tvis = type_visibility (TREE_TYPE (decl));
+      if (tvis == VISIBILITY_ANON
+         || ! DECL_VISIBILITY_SPECIFIED (decl))
+       constrain_visibility (decl, tvis);
+    }
 }
 
+/* By default, static data members and function members receive
+   the visibility of their containing class.  */
+
 static void
 determine_visibility_from_class (tree decl, tree class_type)
 {
-  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
-      && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class_type)))
-    {
-      DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
-      DECL_VISIBILITY_SPECIFIED (decl) = 1;
-    }
-  else if (TREE_CODE (decl) == FUNCTION_DECL
-          && DECL_DECLARED_INLINE_P (decl)
-          && visibility_options.inlines_hidden)
-    {
-      /* Don't change it if it has been set explicitly by user.  */
-      if (!DECL_VISIBILITY_SPECIFIED (decl))
-       {
-         DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
-         DECL_VISIBILITY_SPECIFIED (decl) = 1;
-       }
-    }
-  else if (CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
+  if (DECL_VISIBILITY_SPECIFIED (decl))
+    return;
+
+  if (visibility_options.inlines_hidden
+      /* Don't do this for inline templates; specializations might not be
+        inline, and we don't want them to inherit the hidden
+        visibility.  We'll set it here for all inline instantiations.  */
+      && !processing_template_decl
+      && TREE_CODE (decl) == FUNCTION_DECL
+      && DECL_DECLARED_INLINE_P (decl)
+      && (! DECL_LANG_SPECIFIC (decl)
+         || ! DECL_EXPLICIT_INSTANTIATION (decl)))
+    DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+  else
     {
+      /* Default to the class visibility.  */
       DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
-      DECL_VISIBILITY_SPECIFIED (decl) = 1;
-    }
-  else if (TYPE_CLASS_SCOPE_P (class_type))
-    determine_visibility_from_class (decl, TYPE_CONTEXT (class_type));
-  else if (TYPE_FUNCTION_SCOPE_P (class_type))
-    {
-      tree fn = TYPE_CONTEXT (class_type);
-      DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
-      DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (fn);
+      DECL_VISIBILITY_SPECIFIED (decl)
+       = CLASSTYPE_VISIBILITY_SPECIFIED (class_type);
     }
-  else if (!DECL_VISIBILITY_SPECIFIED (decl))
+
+  /* Give the target a chance to override the visibility associated
+     with DECL.  */
+  if (TREE_CODE (decl) == VAR_DECL
+      && (DECL_TINFO_P (decl)
+         || (DECL_VTABLE_OR_VTT_P (decl)
+             /* Construction virtual tables are not exported because
+                they cannot be referred to from other object files;
+                their name is not standardized by the ABI.  */
+             && !DECL_CONSTRUCTION_VTABLE_P (decl)))
+      && TREE_PUBLIC (decl)
+      && !DECL_REALLY_EXTERN (decl)
+      && !CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
+    targetm.cxx.determine_class_data_visibility (decl);
+}
+
+/* Constrain the visibility of a class TYPE based on the visibility of its
+   field types.  Warn if any fields require lesser visibility.  */
+
+void
+constrain_class_visibility (tree 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 && 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 (!in_main_input_context ())
+             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);
+      }
+
+  binfo = TYPE_BINFO (type);
+  for (i = 0; BINFO_BASE_ITERATE (binfo, i, t); ++i)
     {
-      DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
-      DECL_VISIBILITY_SPECIFIED (decl) = 0;
+      int subvis = type_visibility (TREE_TYPE (t));
+
+      if (subvis == VISIBILITY_ANON)
+        {
+         if (!in_main_input_context())
+           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));
     }
 }
 
@@ -1872,7 +2245,8 @@ import_export_decl (tree decl)
     {
       /* DECL is an implicit instantiation of a function or static
         data member.  */
-      if (flag_implicit_templates
+      if ((flag_implicit_templates
+          && !flag_use_repository)
          || (flag_implicit_inline_templates
              && TREE_CODE (decl) == FUNCTION_DECL
              && DECL_DECLARED_INLINE_P (decl)))
@@ -1950,10 +2324,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);
@@ -1987,6 +2358,8 @@ get_guard (tree decl)
       DECL_ONE_ONLY (guard) = DECL_ONE_ONLY (decl);
       if (TREE_PUBLIC (decl))
        DECL_WEAK (guard) = DECL_WEAK (decl);
+      DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
+      DECL_VISIBILITY_SPECIFIED (guard) = DECL_VISIBILITY_SPECIFIED (decl);
 
       DECL_ARTIFICIAL (guard) = 1;
       DECL_IGNORED_P (guard) = 1;
@@ -2088,14 +2461,16 @@ 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 as artificial because it's not explicitly in the user's
+     source code.  */
+  DECL_ARTIFICIAL (current_function_decl) = 1;
 
   /* Mark this declaration as used to avoid spurious warnings.  */
   TREE_USED (current_function_decl) = 1;
@@ -2109,13 +2484,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 thes 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;
 }
 
@@ -2130,23 +2498,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
@@ -2213,6 +2577,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.  */
@@ -2266,11 +2631,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;
 }
 
@@ -2425,12 +2785,12 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp)
   if (initp)
     {
       if (init)
-        finish_expr_stmt (init);
+       finish_expr_stmt (init);
 
       /* If we're using __cxa_atexit, register a function that calls the
-         destructor for the object.  */
+        destructor for the object.  */
       if (flag_use_cxa_atexit)
-        finish_expr_stmt (register_dtor_fn (decl));
+       finish_expr_stmt (register_dtor_fn (decl));
     }
   else
     finish_expr_stmt (build_cleanup (decl));
@@ -2503,7 +2863,7 @@ do_static_initialization_or_destruction (tree vars, bool initp)
         node = TREE_CHAIN (node))
       /* Do one initialization or destruction.  */
       one_static_initialization_or_destruction (TREE_VALUE (node),
-                                               TREE_PURPOSE (node), initp);
+                                               TREE_PURPOSE (node), initp);
 
     /* Finish up the priority if-stmt body.  */
     finish_then_clause (priority_if_stmt);
@@ -2593,7 +2953,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
@@ -2627,7 +2987,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
@@ -2650,29 +3010,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);
@@ -2690,11 +3027,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.  */
@@ -2702,14 +3037,13 @@ 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.  */
 
 tree
-cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
-                           tree from ATTRIBUTE_UNUSED)
+cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED)
 {
   tree t = *tp;
 
@@ -2791,13 +3125,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;
@@ -2915,7 +3249,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;
@@ -2990,7 +3324,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
@@ -2999,7 +3333,7 @@ cp_finish_file (void)
             DECL_EXTERNAL appropriately, so there's no need to check
             again, and we do not want to clear DECL_EXTERNAL if a
             previous call to import_export_decl set it.
-            
+
             This is done in a separate for cycle, because if some
             deferred function is contained in another deferred
             function later in deferred_fns varray,
@@ -3089,17 +3423,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)
@@ -3121,7 +3449,7 @@ cp_finish_file (void)
   if (VEC_length (tree, pending_statics) != 0)
     {
       check_global_declarations (VEC_address (tree, pending_statics),
-                                VEC_length (tree, pending_statics));
+                                VEC_length (tree, pending_statics));
       emit_debug_global_declarations (VEC_address (tree, pending_statics),
                                      VEC_length (tree, pending_statics));
     }
@@ -3181,15 +3509,15 @@ 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
         because we depend on the form of FN.  */
       args = build_non_dependent_args (args);
+      object = build_non_dependent_expr (object);
       if (TREE_CODE (fn) == DOTSTAR_EXPR)
        object = build_unary_op (ADDR_EXPR, object, 0);
-      object = build_non_dependent_expr (object);
       args = tree_cons (NULL_TREE, object, args);
       /* Now that the arguments are done, transform FN.  */
       fn = build_non_dependent_expr (fn);
@@ -3211,7 +3539,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;
 }
 
@@ -3256,7 +3584,9 @@ mark_used (tree decl)
     }
 
   TREE_USED (decl) = 1;
-  /* If we don't need a value, then we don't need to synthesize DECL.  */ 
+  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;
   /* Normally, we can wait until instantiation-time to synthesize
@@ -3280,9 +3610,9 @@ mark_used (tree decl)
       saved_processing_template_decl = processing_template_decl;
       processing_template_decl = 0;
     }
-  
+
   if (processing_template_decl)
-    return;  
+    return;
 
   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)
       && !TREE_ASM_WRITTEN (decl))
@@ -3334,12 +3664,12 @@ mark_used (tree decl)
        template, we now know that we will need to actually do the
        instantiation. We check that DECL is not an explicit
        instantiation because that is not checked in instantiate_decl.
-       
+
        We put off instantiating functions in order to improve compile
        times.  Maintaining a stack of active functions is expensive,
        and the inliner knows to instantiate any functions it might
        need.  Therefore, we always try to defer instantiation.  */
-    instantiate_decl (decl, /*defer_ok=*/true, 
+    instantiate_decl (decl, /*defer_ok=*/true,
                      /*expl_inst_class_mem_p=*/false);
 
   processing_template_decl = saved_processing_template_decl;