re PR c++/54738 ([C++11][SFINAE] Hard errors for pointer-to-member function expressions)
[gcc.git] / gcc / cp / decl2.c
index a33751cdccf785ce3ffea65155b0d42ba475f554..4cff0516d776060e0fede79ea70f9104fbbbb9db 100644 (file)
@@ -1,7 +1,7 @@
 /* Process declarations and variables for C++ compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010,
+   2011, 2012 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -36,18 +36,16 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "cp-tree.h"
 #include "decl.h"
-#include "output.h"
-#include "except.h"
 #include "toplev.h"
 #include "timevar.h"
 #include "cpplib.h"
 #include "target.h"
 #include "c-family/c-common.h"
-#include "tree-mudflap.h"
+#include "c-family/c-objc.h"
 #include "cgraph.h"
 #include "tree-inline.h"
 #include "c-family/c-pragma.h"
-#include "tree-dump.h"
+#include "dumpfile.h"
 #include "intl.h"
 #include "gimple.h"
 #include "pointer-set.h"
@@ -86,6 +84,7 @@ static void write_out_vars (tree);
 static void import_export_class (tree);
 static tree get_guard_bits (tree);
 static void determine_visibility_from_class (tree, tree);
+static bool determine_hidden_inline (tree);
 static bool decl_defined_p (tree);
 
 /* A list of static class variables.  This is needed, because a
@@ -151,6 +150,9 @@ change_return_type (tree new_ret, tree fntype)
   tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
   tree attrs = TYPE_ATTRIBUTES (fntype);
 
+  if (new_ret == error_mark_node)
+    return fntype;
+
   if (same_type_p (new_ret, TREE_TYPE (fntype)))
     return fntype;
 
@@ -161,8 +163,7 @@ change_return_type (tree new_ret, tree fntype)
     }
   else
     newtype = build_method_type_directly
-      (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
-       new_ret, TREE_CHAIN (args));
+      (class_of_this_parm (fntype), new_ret, TREE_CHAIN (args));
   if (raises)
     newtype = build_exception_variant (newtype, raises);
   if (attrs)
@@ -243,7 +244,7 @@ maybe_retrofit_in_chrg (tree fn)
   basetype = TREE_TYPE (TREE_VALUE (arg_types));
   arg_types = TREE_CHAIN (arg_types);
 
-  parms = TREE_CHAIN (DECL_ARGUMENTS (fn));
+  parms = DECL_CHAIN (DECL_ARGUMENTS (fn));
 
   /* If this is a subobject constructor or destructor, our caller will
      pass us a pointer to our VTT.  */
@@ -252,7 +253,7 @@ maybe_retrofit_in_chrg (tree fn)
       parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type);
 
       /* First add it to DECL_ARGUMENTS between 'this' and the real args...  */
-      TREE_CHAIN (parm) = parms;
+      DECL_CHAIN (parm) = parms;
       parms = parm;
 
       /* ...and then to TYPE_ARG_TYPES.  */
@@ -263,12 +264,12 @@ maybe_retrofit_in_chrg (tree fn)
 
   /* Then add the in-charge parm (before the VTT parm).  */
   parm = build_artificial_parm (in_charge_identifier, integer_type_node);
-  TREE_CHAIN (parm) = parms;
+  DECL_CHAIN (parm) = parms;
   parms = parm;
   arg_types = hash_tree_chain (integer_type_node, arg_types);
 
   /* Insert our new parameter(s) into the list.  */
-  TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms;
+  DECL_CHAIN (DECL_ARGUMENTS (fn)) = parms;
 
   /* And rebuild the function type.  */
   fntype = build_method_type_directly (basetype, TREE_TYPE (TREE_TYPE (fn)),
@@ -334,7 +335,7 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags)
    along the way.  */
 
 tree
-grok_array_decl (tree array_expr, tree index_exp)
+grok_array_decl (location_t loc, tree array_expr, tree index_exp)
 {
   tree type;
   tree expr;
@@ -348,8 +349,8 @@ grok_array_decl (tree array_expr, tree index_exp)
     {
       if (type_dependent_expression_p (array_expr)
          || type_dependent_expression_p (index_exp))
-       return build_min_nt (ARRAY_REF, array_expr, index_exp,
-                            NULL_TREE, NULL_TREE);
+       return build_min_nt_loc (loc, ARRAY_REF, array_expr, index_exp,
+                                NULL_TREE, NULL_TREE);
       array_expr = build_non_dependent_expr (array_expr);
       index_exp = build_non_dependent_expr (index_exp);
     }
@@ -360,9 +361,8 @@ grok_array_decl (tree array_expr, tree index_exp)
 
   /* If they have an `operator[]', use that.  */
   if (MAYBE_CLASS_TYPE_P (type) || MAYBE_CLASS_TYPE_P (TREE_TYPE (index_exp)))
-    expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL,
-                        array_expr, index_exp, NULL_TREE,
-                        /*overloaded_p=*/NULL, tf_warning_or_error);
+    expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, array_expr, index_exp,
+                        NULL_TREE, /*overload=*/NULL, tf_warning_or_error);
   else
     {
       tree p1, p2, i1, i2;
@@ -371,7 +371,7 @@ grok_array_decl (tree array_expr, tree index_exp)
         It is a little-known fact that, if `a' is an array and `i' is
         an int, you can write `i[a]', which means the same thing as
         `a[i]'.  */
-      if (TREE_CODE (type) == ARRAY_TYPE)
+      if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
        p1 = array_expr;
       else
        p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false);
@@ -419,7 +419,8 @@ grok_array_decl (tree array_expr, tree index_exp)
    Implements ARM $5.3.4.  This is called from the parser.  */
 
 tree
-delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete)
+delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete,
+              tsubst_flags_t complain)
 {
   tree t, type;
 
@@ -436,9 +437,8 @@ delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete)
     }
 
   /* An array can't have been allocated by new, so complain.  */
-  if (TREE_CODE (exp) == VAR_DECL
-      && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
-    warning (0, "deleting array %q#D", exp);
+  if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+    warning (0, "deleting array %q#E", exp);
 
   t = build_expr_type_conversion (WANT_POINTER, exp, true);
 
@@ -475,10 +475,11 @@ delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete)
   if (doing_vec)
     return build_vec_delete (t, /*maxindex=*/NULL_TREE,
                             sfk_deleting_destructor,
-                            use_global_delete);
+                            use_global_delete, complain);
   else
     return build_delete (type, t, sfk_deleting_destructor,
-                        LOOKUP_NORMAL, use_global_delete);
+                        LOOKUP_NORMAL, use_global_delete,
+                        complain);
 }
 
 /* Report an error if the indicated template declaration is not the
@@ -493,6 +494,7 @@ check_member_template (tree tmpl)
   decl = DECL_TEMPLATE_RESULT (tmpl);
 
   if (TREE_CODE (decl) == FUNCTION_DECL
+      || DECL_ALIAS_TEMPLATE_P (tmpl)
       || (TREE_CODE (decl) == TYPE_DECL
          && MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))))
     {
@@ -625,7 +627,7 @@ check_classfn (tree ctype, tree function, tree template_parms)
          && !comp_template_parms (template_parms,
                                   DECL_TEMPLATE_PARMS (function)))
        {
-         error ("template parameter lists provided don't match the "
+         error ("template parameter lists provided don%'t match the "
                 "template parameters of %qD", function);
          return error_mark_node;
        }
@@ -768,25 +770,12 @@ finish_static_data_member_decl (tree decl,
   if (! processing_template_decl)
     VEC_safe_push (tree, gc, pending_statics, decl);
 
-  if (LOCAL_CLASS_P (current_class_type))
+  if (LOCAL_CLASS_P (current_class_type)
+      /* We already complained about the template definition.  */
+      && !DECL_TEMPLATE_INSTANTIATION (decl))
     permerror (input_location, "local class %q#T shall not have static data member %q#D",
               current_class_type, decl);
 
-  /* Static consts need not be initialized in the class definition.  */
-  if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
-    {
-      static int explained = 0;
-
-      error ("initializer invalid for static member with constructor");
-      if (!explained)
-       {
-         error ("(an out of class initialization is required)");
-         explained = 1;
-       }
-      init = NULL_TREE;
-    }
-
-  DECL_INITIAL (decl) = init;
   DECL_IN_AGGR_P (decl) = 1;
 
   if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
@@ -809,7 +798,7 @@ grokfield (const cp_declarator *declarator,
 {
   tree value;
   const char *asmspec = 0;
-  int flags = LOOKUP_ONLYCONVERTING;
+  int flags;
   tree name;
 
   if (init
@@ -861,9 +850,6 @@ grokfield (const cp_declarator *declarator,
       DECL_NONLOCAL (value) = 1;
       DECL_CONTEXT (value) = current_class_type;
 
-      if (processing_template_decl)
-       value = push_template_decl (value);
-
       if (attrlist)
        {
          int attrflags = 0;
@@ -877,11 +863,18 @@ grokfield (const cp_declarator *declarator,
          cplus_decl_attributes (&value, attrlist, attrflags);
        }
 
-      if (declspecs->specs[(int)ds_typedef]
+      if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)
           && TREE_TYPE (value) != error_mark_node
           && TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value))) != value)
-       cp_set_underlying_type (value);
+       set_underlying_type (value);
 
+      /* It's important that push_template_decl below follows
+        set_underlying_type above so that the created template
+        carries the properly set type of VALUE.  */
+      if (processing_template_decl)
+       value = push_template_decl (value);
+
+      record_locally_defined_typedef (value);
       return value;
     }
 
@@ -915,6 +908,8 @@ grokfield (const cp_declarator *declarator,
                  DECL_DECLARED_INLINE_P (value) = 1;
                }
            }
+         else if (TREE_CODE (init) == DEFAULT_ARG)
+           error ("invalid initializer for member function %qD", value);
          else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
            {
              if (integer_zerop (init))
@@ -932,15 +927,15 @@ grokfield (const cp_declarator *declarator,
                     value);
            }
        }
-      else if (pedantic && TREE_CODE (value) != VAR_DECL)
-       /* Already complained in grokdeclarator.  */
-       init = NULL_TREE;
+      else if (TREE_CODE (value) == FIELD_DECL)
+       /* C++11 NSDMI, keep going.  */;
+      else if (TREE_CODE (value) != VAR_DECL)
+       gcc_unreachable ();
       else if (!processing_template_decl)
        {
          if (TREE_CODE (init) == CONSTRUCTOR)
-           init = digest_init (TREE_TYPE (value), init);
-         else
-           init = integral_constant_value (init);
+           init = digest_init (TREE_TYPE (value), init, tf_warning_or_error);
+         init = maybe_constant_init (init);
 
          if (init != error_mark_node && !TREE_CONSTANT (init))
            {
@@ -969,6 +964,12 @@ grokfield (const cp_declarator *declarator,
   if (attrlist)
     cplus_decl_attributes (&value, attrlist, 0);
 
+  if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
+      && CONSTRUCTOR_IS_DIRECT_INIT (init))
+    flags = LOOKUP_NORMAL;
+  else
+    flags = LOOKUP_IMPLICIT;
+
   switch (TREE_CODE (value))
     {
     case VAR_DECL:
@@ -983,7 +984,6 @@ grokfield (const cp_declarator *declarator,
        init = error_mark_node;
       cp_finish_decl (value, init, /*init_const_expr_p=*/false,
                      NULL_TREE, flags);
-      DECL_INITIAL (value) = init;
       DECL_IN_AGGR_P (value) = 1;
       return value;
 
@@ -1067,7 +1067,11 @@ grokbitfield (const cp_declarator *declarator,
 
   if (width != error_mark_node)
     {
-      constant_expression_warning (width);
+      /* The width must be an integer type.  */
+      if (!type_dependent_expression_p (width)
+         && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width)))
+       error ("width of bit-field %qD has non-integral type %qT", value,
+              TREE_TYPE (width));
       DECL_INITIAL (value) = width;
       SET_DECL_C_BIT_FIELD (value);
     }
@@ -1100,6 +1104,11 @@ is_late_template_attribute (tree attr, tree decl)
   if (is_attribute_p ("weak", name))
     return true;
 
+  /* Attribute unused is applied directly, as it appertains to
+     decls. */
+  if (is_attribute_p ("unused", name))
+    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))
@@ -1197,9 +1206,9 @@ save_template_attributes (tree *attr_p, tree *decl_p)
 
   old_attrs = *q;
 
-  /* Place the late attributes at the beginning of the attribute
+  /* Merge the late attributes at the beginning with the attribute
      list.  */
-  TREE_CHAIN (tree_last (late_attrs)) = *q;
+  late_attrs = merge_attributes (late_attrs, *q);
   *q = late_attrs;
 
   if (!DECL_P (*decl_p) && *decl_p == TYPE_MAIN_VARIANT (*decl_p))
@@ -1259,8 +1268,7 @@ cp_reconstruct_complex_type (tree type, tree bottom)
         so we must compensate by getting rid of it.  */
       outer
        = build_method_type_directly
-           (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))),
-            inner,
+           (class_of_this_parm (type), inner,
             TREE_CHAIN (TYPE_ARG_TYPES (type)));
     }
   else if (TREE_CODE (type) == OFFSET_TYPE)
@@ -1276,6 +1284,25 @@ cp_reconstruct_complex_type (tree type, tree bottom)
   return cp_build_qualified_type (outer, cp_type_quals (type));
 }
 
+/* Replaces any constexpr expression that may be into the attributes
+   arguments with their reduced value.  */
+
+static void
+cp_check_const_attributes (tree attributes)
+{
+  tree attr;
+  for (attr = attributes; attr; attr = TREE_CHAIN (attr))
+    {
+      tree arg;
+      for (arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg))
+       {
+         tree expr = TREE_VALUE (arg);
+         if (EXPR_P (expr))
+           TREE_VALUE (arg) = maybe_constant_value (expr);
+       }
+    }
+}
+
 /* Like decl_attributes, but handle C++ complexity.  */
 
 void
@@ -1296,6 +1323,8 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
        return;
     }
 
+  cp_check_const_attributes (attributes);
+
   if (TREE_CODE (*decl) == TEMPLATE_DECL)
     decl = &DECL_TEMPLATE_RESULT (*decl);
 
@@ -1318,11 +1347,14 @@ build_anon_union_vars (tree type, tree object)
   /* Rather than write the code to handle the non-union case,
      just give an error.  */
   if (TREE_CODE (type) != UNION_TYPE)
-    error ("anonymous struct not inside named type");
+    {
+      error ("anonymous struct not inside named type");
+      return error_mark_node;
+    }
 
   for (field = TYPE_FIELDS (type);
        field != NULL_TREE;
-       field = TREE_CHAIN (field))
+       field = DECL_CHAIN (field))
     {
       tree decl;
       tree ref;
@@ -1342,8 +1374,8 @@ build_anon_union_vars (tree type, tree object)
        permerror (input_location, "protected member %q+#D in anonymous union", field);
 
       if (processing_template_decl)
-       ref = build_min_nt (COMPONENT_REF, object,
-                           DECL_NAME (field), NULL_TREE);
+       ref = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, object,
+                               DECL_NAME (field), NULL_TREE);
       else
        ref = build_class_member_access_expr (object, field, NULL_TREE,
                                              false, tf_warning_or_error);
@@ -1422,17 +1454,13 @@ finish_anon_union (tree anon_union_decl)
       /* Use main_decl to set the mangled name.  */
       DECL_NAME (anon_union_decl) = DECL_NAME (main_decl);
       maybe_commonize_var (anon_union_decl);
-      mangle_decl (anon_union_decl);
+      if (TREE_STATIC (anon_union_decl) || DECL_EXTERNAL (anon_union_decl))
+       mangle_decl (anon_union_decl);
       DECL_NAME (anon_union_decl) = NULL_TREE;
     }
 
   pushdecl (anon_union_decl);
-  if (building_stmt_tree ()
-      && at_function_scope_p ())
-    add_decl_expr (anon_union_decl);
-  else if (!processing_template_decl)
-    rest_of_decl_compilation (anon_union_decl,
-                             toplevel_bindings_p (), at_eof);
+  cp_finish_decl (anon_union_decl, NULL_TREE, false, NULL_TREE, 0);
 }
 \f
 /* Auxiliary functions to make type signatures for
@@ -1653,6 +1681,7 @@ maybe_make_one_only (tree decl)
          DECL_COMDAT (decl) = 1;
          /* Mark it needed so we don't forget to emit it.  */
          mark_decl_referenced (decl);
+         TREE_USED (decl) = 1;
        }
     }
 }
@@ -1758,10 +1787,7 @@ var_finalized_p (tree var)
 void
 mark_needed (tree decl)
 {
-  /* It's possible that we no longer need to set
-     TREE_SYMBOL_REFERENCED here directly, but doing so is
-     harmless.  */
-  TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = 1;
+  TREE_USED (decl) = 1;
   mark_decl_referenced (decl);
 }
 
@@ -1787,13 +1813,12 @@ decl_needed_p (tree decl)
     return true;
   /* 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)
-         && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
+  if (TREE_USED (decl))
       return true;
   /* Functions marked "dllexport" must be emitted so that they are
      visible to other DLLs.  */
-  if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
+  if (flag_keep_inline_dllexport
+      && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
     return true;
   /* Otherwise, DECL does not need to be emitted -- yet.  A subsequent
      reference to DECL might cause it to be emitted later.  */
@@ -1809,7 +1834,7 @@ maybe_emit_vtables (tree ctype)
   tree vtbl;
   tree primary_vtbl;
   int needed = 0;
-  struct varpool_node *current = NULL, *last = NULL, *first = NULL;
+  struct varpool_node *current = NULL, *last = NULL;
 
   /* If the vtables for this class have already been emitted there is
      nothing more to do.  */
@@ -1827,7 +1852,7 @@ maybe_emit_vtables (tree ctype)
     determine_key_method (ctype);
 
   /* See if any of the vtables are needed.  */
-  for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl))
+  for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl))
     {
       import_export_decl (vtbl);
       if (DECL_NOT_REALLY_EXTERN (vtbl) && decl_needed_p (vtbl))
@@ -1846,17 +1871,19 @@ maybe_emit_vtables (tree ctype)
 
   /* The ABI requires that we emit all of the vtables if we emit any
      of them.  */
-  for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl))
+  for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl))
     {
       /* Mark entities references from the virtual table as used.  */
       mark_vtable_entries (vtbl);
 
       if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
        {
-         tree expr = store_init_value (vtbl, DECL_INITIAL (vtbl), LOOKUP_NORMAL);
+         VEC(tree,gc)* cleanups = NULL;
+         tree expr = store_init_value (vtbl, DECL_INITIAL (vtbl), &cleanups,
+                                       LOOKUP_NORMAL);
 
          /* It had better be all done at compile-time.  */
-         gcc_assert (!expr);
+         gcc_assert (!expr && !cleanups);
        }
 
       /* Write it out.  */
@@ -1867,20 +1894,15 @@ 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))
+      else if (DECL_ONE_ONLY (vtbl))
        {
          current = varpool_node (vtbl);
          if (last)
-           last->same_comdat_group = current;
+           symtab_add_to_same_comdat_group ((symtab_node) current, (symtab_node) last);
          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);
@@ -1928,10 +1950,12 @@ type_visibility (tree type)
 }
 
 /* Limit the visibility of DECL to VISIBILITY, if not explicitly
-   specified (or if VISIBILITY is static).  */
+   specified (or if VISIBILITY is static).  If TMPL is true, this
+   constraint is for a template argument, and takes precedence
+   over explicitly-specified visibility on the template.  */
 
-static bool
-constrain_visibility (tree decl, int visibility)
+static void
+constrain_visibility (tree decl, int visibility, bool tmpl)
 {
   if (visibility == VISIBILITY_ANON)
     {
@@ -1949,12 +1973,12 @@ constrain_visibility (tree decl, int visibility)
        }
     }
   else if (visibility > DECL_VISIBILITY (decl)
-          && !DECL_VISIBILITY_SPECIFIED (decl))
+          && (tmpl || !DECL_VISIBILITY_SPECIFIED (decl)))
     {
       DECL_VISIBILITY (decl) = (enum symbol_visibility) visibility;
-      return true;
+      /* This visibility was not specified.  */
+      DECL_VISIBILITY_SPECIFIED (decl) = false;
     }
-  return false;
 }
 
 /* Constrain the visibility of DECL based on the visibility of its template
@@ -1990,7 +2014,7 @@ constrain_visibility_for_template (tree decl, tree targs)
            }
        }
       if (vis)
-       constrain_visibility (decl, vis);
+       constrain_visibility (decl, vis, true);
     }
 }
 
@@ -2065,14 +2089,29 @@ determine_visibility (tree decl)
             containing function by default, except that
             -fvisibility-inlines-hidden doesn't affect them.  */
          tree fn = DECL_CONTEXT (decl);
-         if (DECL_VISIBILITY_SPECIFIED (fn) || ! DECL_CLASS_SCOPE_P (fn))
+         if (DECL_VISIBILITY_SPECIFIED (fn))
            {
              DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
              DECL_VISIBILITY_SPECIFIED (decl) = 
                DECL_VISIBILITY_SPECIFIED (fn);
            }
          else
-           determine_visibility_from_class (decl, DECL_CONTEXT (fn));
+           {
+             if (DECL_CLASS_SCOPE_P (fn))
+               determine_visibility_from_class (decl, DECL_CONTEXT (fn));
+             else if (determine_hidden_inline (fn))
+               {
+                 DECL_VISIBILITY (decl) = default_visibility;
+                 DECL_VISIBILITY_SPECIFIED (decl) =
+                   visibility_options.inpragma;
+               }
+             else
+               {
+                 DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
+                 DECL_VISIBILITY_SPECIFIED (decl) =
+                   DECL_VISIBILITY_SPECIFIED (fn);
+               }
+           }
 
          /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set,
             but have no TEMPLATE_INFO, so don't try to check it.  */
@@ -2086,8 +2125,9 @@ determine_visibility (tree decl)
          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);
+             || (CLASS_TYPE_P (underlying_type)
+                 && CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type)))
+           constrain_visibility (decl, underlying_vis, false);
          else
            DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
        }
@@ -2095,7 +2135,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))));
+           (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))), false);
 
          /* Give the target a chance to override the visibility associated
             with DECL.  */
@@ -2110,10 +2150,15 @@ determine_visibility (tree decl)
           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;
+          if (determine_hidden_inline (decl))
+           DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+         else
+            {
+             /* 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;
+            }
        }
     }
 
@@ -2125,23 +2170,52 @@ determine_visibility (tree decl)
                    ? TYPE_TEMPLATE_INFO (TREE_TYPE (decl))
                    : DECL_TEMPLATE_INFO (decl));
       tree args = TI_ARGS (tinfo);
+      tree attribs = (TREE_CODE (decl) == TYPE_DECL
+                     ? TYPE_ATTRIBUTES (TREE_TYPE (decl))
+                     : DECL_ATTRIBUTES (decl));
       
       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);
+             if (!DECL_VISIBILITY_SPECIFIED (pattern)
+                 && determine_hidden_inline (decl))
+               DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+             else
+               {
+                 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 (args
+             /* Template argument visibility outweighs #pragma or namespace
+                visibility, but not an explicit attribute.  */
+             && !lookup_attribute ("visibility", attribs))
+           {
+             int depth = TMPL_ARGS_DEPTH (args);
+             int class_depth = 0;
+             if (class_type && CLASSTYPE_TEMPLATE_INFO (class_type))
+               class_depth = TMPL_ARGS_DEPTH (CLASSTYPE_TI_ARGS (class_type));
+             if (DECL_VISIBILITY_SPECIFIED (decl))
+               {
+                 /* A class template member with explicit visibility
+                    overrides the class visibility, so we need to apply
+                    all the levels of template args directly.  */
+                 int i;
+                 for (i = 1; i <= depth; ++i)
+                   {
+                     tree lev = TMPL_ARGS_LEVEL (args, i);
+                     constrain_visibility_for_template (decl, lev);
+                   }
+               }
+             else if (depth > class_depth)
+               /* Limit visibility based on its template arguments.  */
+               constrain_visibility_for_template (decl, args);
+           }
        }
     }
 
@@ -2151,14 +2225,14 @@ determine_visibility (tree 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_ANON);
+    constrain_visibility (decl, VISIBILITY_ANON, false);
   else if (TREE_CODE (decl) != TYPE_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);
+       constrain_visibility (decl, tvis, false);
     }
   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
@@ -2169,7 +2243,7 @@ determine_visibility (tree decl)
 
        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);
+    constrain_visibility (decl, VISIBILITY_ANON, false);
 
   /* If visibility changed and DECL already has DECL_RTL, ensure
      symbol flags are updated.  */
@@ -2190,15 +2264,7 @@ determine_visibility_from_class (tree decl, tree 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)))
+  if (determine_hidden_inline (decl))
     DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
   else
     {
@@ -2223,6 +2289,23 @@ determine_visibility_from_class (tree decl, tree class_type)
     targetm.cxx.determine_class_data_visibility (decl);
 }
 
+/* Returns true iff DECL is an inline that should get hidden visibility
+   because of -fvisibility-inlines-hidden.  */
+
+static bool
+determine_hidden_inline (tree decl)
+{
+  return (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)));
+}
+
 /* Constrain the visibility of a class TYPE based on the visibility of its
    field types.  Warn if any fields require lesser visibility.  */
 
@@ -2243,7 +2326,7 @@ constrain_class_visibility (tree type)
   if (CLASSTYPE_VISIBILITY_SPECIFIED (type))
     vis = VISIBILITY_INTERNAL;
 
-  for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
+  for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
     if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node)
       {
        tree ftype = strip_pointer_or_array_types (TREE_TYPE (t));
@@ -2582,7 +2665,8 @@ build_cleanup (tree decl)
     temp = build_address (decl);
   temp = build_delete (TREE_TYPE (temp), temp,
                       sfk_complete_destructor,
-                      LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
+                      LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0,
+                      tf_warning_or_error);
   return temp;
 }
 
@@ -2704,7 +2788,7 @@ start_objects (int method_type, int initp)
 {
   tree body;
   tree fndecl;
-  char type[10];
+  char type[14];
 
   /* Make ctor or dtor function.  METHOD_TYPE may be 'I' or 'D'.  */
 
@@ -2718,10 +2802,10 @@ start_objects (int method_type, int initp)
       joiner = '_';
 #endif
 
-      sprintf (type, "%c%c%.5u", method_type, joiner, initp);
+      sprintf (type, "sub_%c%c%.5u", method_type, joiner, initp);
     }
   else
-    sprintf (type, "%c", method_type);
+    sprintf (type, "sub_%c", method_type);
 
   fndecl = build_lang_decl (FUNCTION_DECL,
                            get_file_function_name (type),
@@ -2869,7 +2953,7 @@ start_static_storage_duration_function (unsigned count)
   DECL_CONTEXT (priority_decl) = ssdf_decl;
   TREE_USED (priority_decl) = 1;
 
-  TREE_CHAIN (initialize_p_decl) = priority_decl;
+  DECL_CHAIN (initialize_p_decl) = priority_decl;
   DECL_ARGUMENTS (ssdf_decl) = initialize_p_decl;
 
   /* Put the function in the global scope.  */
@@ -2958,8 +3042,8 @@ get_priority_info (int priority)
    it's DECL_CONTECT() properly set.  */
 static tree 
 fix_temporary_vars_context_r (tree *node,
-                             int  *unused ATTRIBUTE_UNUSED,
-                             void *unused1 ATTRIBUTE_UNUSED)
+                             int  * /*unused*/,
+                             void * /*unused1*/)
 {
   gcc_assert (current_function_decl);
 
@@ -2967,7 +3051,7 @@ fix_temporary_vars_context_r (tree *node,
     {
       tree var;
 
-      for (var = BIND_EXPR_VARS (*node); var; var = TREE_CHAIN (var))
+      for (var = BIND_EXPR_VARS (*node); var; var = DECL_CHAIN (var))
        if (TREE_CODE (var) == VAR_DECL
          && !DECL_NAME (var)
          && DECL_ARTIFICIAL (var)
@@ -3301,7 +3385,7 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
 
   /* Call the static storage duration function with appropriate
      arguments.  */
-  for (i = 0; VEC_iterate (tree, ssdf_decls, i, fndecl); ++i)
+  FOR_EACH_VEC_ELT (tree, ssdf_decls, i, fndecl)
     {
       /* Calls to pure or const functions will expand to nothing.  */
       if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
@@ -3347,42 +3431,6 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
   return 0;
 }
 
-/* Called via LANGHOOK_CALLGRAPH_ANALYZE_EXPR.  It is supposed to mark
-   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 t = *tp;
-
-  switch (TREE_CODE (t))
-    {
-    case PTRMEM_CST:
-      if (TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
-       cgraph_mark_address_taken_node (cgraph_node (PTRMEM_CST_MEMBER (t)));
-      break;
-    case BASELINK:
-      if (TREE_CODE (BASELINK_FUNCTIONS (t)) == FUNCTION_DECL)
-       cgraph_mark_address_taken_node (cgraph_node (BASELINK_FUNCTIONS (t)));
-      break;
-    case VAR_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));
-      break;
-    default:
-      break;
-    }
-
-  return NULL;
-}
-
 /* Java requires that we be able to reference a local address for a
    method, and not be confused by PLT entries.  If hidden aliases are
    supported, collect and return all the functions for which we should
@@ -3398,9 +3446,9 @@ collect_candidates_for_java_method_aliases (void)
   return candidates;
 #endif
 
-  for (node = cgraph_nodes; node ; node = node->next)
+  FOR_EACH_FUNCTION (node)
     {
-      tree fndecl = node->decl;
+      tree fndecl = node->symbol.decl;
 
       if (DECL_CONTEXT (fndecl)
          && TYPE_P (DECL_CONTEXT (fndecl))
@@ -3432,9 +3480,9 @@ build_java_method_aliases (struct pointer_set_t *candidates)
   return;
 #endif
 
-  for (node = cgraph_nodes; node ; node = node->next)
+  FOR_EACH_FUNCTION (node)
     {
-      tree fndecl = node->decl;
+      tree fndecl = node->symbol.decl;
 
       if (TREE_ASM_WRITTEN (fndecl)
          && pointer_set_contains (candidates, fndecl))
@@ -3538,6 +3586,51 @@ decl_defined_p (tree decl)
     }
 }
 
+/* Nonzero for a VAR_DECL whose value can be used in a constant expression.
+
+      [expr.const]
+
+      An integral constant-expression can only involve ... const
+      variables of integral or enumeration types initialized with
+      constant expressions ...
+
+      C++0x also allows constexpr variables and temporaries initialized
+      with constant expressions.  We handle the former here, but the latter
+      are just folded away in cxx_eval_constant_expression.
+
+   The standard does not require that the expression be non-volatile.
+   G++ implements the proposed correction in DR 457.  */
+
+bool
+decl_constant_var_p (tree decl)
+{
+  if (!decl_maybe_constant_var_p (decl))
+    return false;
+
+  /* We don't know if a template static data member is initialized with
+     a constant expression until we instantiate its initializer.  Even
+     in the case of a constexpr variable, we can't treat it as a
+     constant until its initializer is complete in case it's used in
+     its own initializer.  */
+  mark_used (decl);
+  return DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl);
+}
+
+/* Returns true if DECL could be a symbolic constant variable, depending on
+   its initializer.  */
+
+bool
+decl_maybe_constant_var_p (tree decl)
+{
+  tree type = TREE_TYPE (decl);
+  if (TREE_CODE (decl) != VAR_DECL)
+    return false;
+  if (DECL_DECLARED_CONSTEXPR_P (decl))
+    return true;
+  return (CP_TYPE_CONST_NON_VOLATILE_P (type)
+         && INTEGRAL_OR_ENUMERATION_TYPE_P (type));
+}
+
 /* Complain that DECL uses a type with no linkage but is never defined.  */
 
 static void
@@ -3565,6 +3658,15 @@ collect_all_refs (const char *source_file)
   collect_ada_namespace (global_namespace, source_file);
 }
 
+/* Clear DECL_EXTERNAL for NODE.  */
+
+static bool
+clear_decl_external (struct cgraph_node *node, void * /*data*/)
+{
+  DECL_EXTERNAL (node->symbol.decl) = 0;
+  return false;
+}
+
 /* 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
@@ -3586,12 +3688,15 @@ cp_write_global_declarations (void)
   at_eof = 1;
 
   /* Bad parse errors.  Just forget about it.  */
-  if (! global_bindings_p () || current_class_type || decl_namespace_list)
+  if (! global_bindings_p () || current_class_type
+      || !VEC_empty (tree,decl_namespace_list))
     return;
 
   if (pch_file)
     c_common_write_pch ();
 
+  cgraph_process_same_body_aliases ();
+
   /* Handle -fdump-ada-spec[-slim] */
   if (dump_enabled_p (TDI_ada))
     {
@@ -3605,6 +3710,8 @@ cp_write_global_declarations (void)
 
   /* FIXME - huh?  was  input_line -= 1;*/
 
+  timevar_start (TV_PHASE_DEFERRED);
+
   /* We now have to write out all the stuff we put off writing out.
      These include:
 
@@ -3621,8 +3728,6 @@ cp_write_global_declarations (void)
      generating the initializer for an object may cause templates to be
      instantiated, etc., etc.  */
 
-  timevar_push (TV_VARCONST);
-
   emit_support_tinfos ();
 
   do
@@ -3742,7 +3847,7 @@ cp_write_global_declarations (void)
       /* Go through the set of inline functions whose bodies have not
         been emitted yet.  If out-of-line copies of these functions
         are required, emit them.  */
-      for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i)
+      FOR_EACH_VEC_ELT (tree, deferred_fns, i, decl)
        {
          /* Does it need synthesizing?  */
          if (DECL_DEFAULTED_FN (decl) && ! DECL_INITIAL (decl)
@@ -3786,34 +3891,23 @@ cp_write_global_declarations (void)
              && DECL_INITIAL (decl)
              && decl_needed_p (decl))
            {
-             struct cgraph_node *node = cgraph_get_node (decl), *alias, *next;
+             struct cgraph_node *node, *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;
-               }
+             node = cgraph_get_node (decl);
+             if (node->same_body_alias)
+               node = cgraph_alias_aliased_node (node);
+
+             cgraph_for_node_and_aliases (node, clear_decl_external,
+                                          NULL, true);
              /* 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;
+             if (node->symbol.same_comdat_group)
+               for (next = cgraph (node->symbol.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;
-                     }
-                 }
+                    next = cgraph (next->symbol.same_comdat_group))
+                 cgraph_for_node_and_aliases (next, clear_decl_external,
+                                              NULL, true);
            }
 
          /* If we're going to need to write this function out, and
@@ -3823,7 +3917,7 @@ cp_write_global_declarations (void)
          if (!DECL_EXTERNAL (decl)
              && decl_needed_p (decl)
              && !TREE_ASM_WRITTEN (decl)
-             && !cgraph_node (decl)->local.finalized)
+             && !cgraph_get_node (decl)->local.finalized)
            {
              /* We will output the function; no longer consider it in this
                 loop.  */
@@ -3844,7 +3938,7 @@ cp_write_global_declarations (void)
        reconsider = true;
 
       /* Static data members are just like namespace-scope globals.  */
-      for (i = 0; VEC_iterate (tree, pending_statics, i, decl); ++i)
+      FOR_EACH_VEC_ELT (tree, pending_statics, i, decl)
        {
          if (var_finalized_p (decl) || DECL_REALLY_EXTERN (decl)
              /* Don't write it out if we haven't seen a definition.  */
@@ -3866,7 +3960,7 @@ cp_write_global_declarations (void)
   while (reconsider);
 
   /* All used inline functions must have a definition at this point.  */
-  for (i = 0; VEC_iterate (tree, deferred_fns, i, decl); ++i)
+  FOR_EACH_VEC_ELT (tree, deferred_fns, i, decl)
     {
       if (/* Check online inline functions that were actually used.  */
          DECL_ODR_USED (decl) && DECL_DECLARED_INLINE_P (decl)
@@ -3876,10 +3970,10 @@ cp_write_global_declarations (void)
             #pragma interface, etc.) we decided not to emit the
             definition here.  */
          && !DECL_INITIAL (decl)
-         /* An explicit instantiation can be used to specify
-            that the body is in another unit. It will have
-            already verified there was a definition.  */
-         && !DECL_EXPLICIT_INSTANTIATION (decl))
+         /* Don't complain if the template was defined.  */
+         && !(DECL_TEMPLATE_INSTANTIATION (decl)
+              && DECL_INITIAL (DECL_TEMPLATE_RESULT
+                               (template_for_substitution (decl)))))
        {
          warning (0, "inline function %q+D used but never defined", decl);
          /* Avoid a duplicate warning from check_global_declaration_1.  */
@@ -3888,10 +3982,18 @@ cp_write_global_declarations (void)
     }
 
   /* So must decls that use a type with no linkage.  */
-  for (i = 0; VEC_iterate (tree, no_linkage_decls, i, decl); ++i)
+  FOR_EACH_VEC_ELT (tree, no_linkage_decls, i, decl)
     if (!decl_defined_p (decl))
       no_linkage_error (decl);
 
+  /* Then, do the Objective-C stuff.  This is where all the
+     Objective-C module stuff gets generated (symtab,
+     class/protocol/selector lists etc).  This must be done after C++
+     templates, destructors etc. so that selectors used in C++
+     templates are properly allocated.  */
+  if (c_dialect_objc ())
+    objc_write_global_declarations ();
+
   /* We give C linkage to static constructors and destructors.  */
   push_lang_context (lang_name_c);
 
@@ -3921,7 +4023,13 @@ cp_write_global_declarations (void)
   /* Collect candidates for Java hidden aliases.  */
   candidates = collect_candidates_for_java_method_aliases ();
 
-  cgraph_finalize_compilation_unit ();
+  timevar_stop (TV_PHASE_DEFERRED);
+  timevar_start (TV_PHASE_OPT_GEN);
+
+  finalize_compilation_unit ();
+
+  timevar_stop (TV_PHASE_OPT_GEN);
+  timevar_start (TV_PHASE_CHECK_DBGINFO);
 
   /* Now, issue warnings about static, but not defined, functions,
      etc., and emit debugging information.  */
@@ -3934,6 +4042,8 @@ cp_write_global_declarations (void)
                                      VEC_length (tree, pending_statics));
     }
 
+  perform_deferred_noexcept_checks ();
+
   /* Generate hidden aliases for Java.  */
   if (candidates)
     {
@@ -3956,8 +4066,6 @@ cp_write_global_declarations (void)
       }
   }
 
-  timevar_pop (TV_VARCONST);
-
   if (flag_detailed_statistics)
     {
       dump_tree_statistics ();
@@ -3968,6 +4076,8 @@ cp_write_global_declarations (void)
 #ifdef ENABLE_CHECKING
   validate_conversion_obstack ();
 #endif /* ENABLE_CHECKING */
+
+  timevar_stop (TV_PHASE_CHECK_DBGINFO);
 }
 
 /* FN is an OFFSET_REF, DOTSTAR_EXPR or MEMBER_REF indicating the
@@ -3977,7 +4087,8 @@ cp_write_global_declarations (void)
    ARGS.  */
 
 tree
-build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args)
+build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args,
+                                tsubst_flags_t complain)
 {
   tree orig_fn;
   VEC(tree,gc) *orig_args = NULL;
@@ -4002,9 +4113,12 @@ build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args)
         because we depend on the form of FN.  */
       make_args_non_dependent (*args);
       object = build_non_dependent_expr (object);
-      if (TREE_CODE (fn) == DOTSTAR_EXPR)
-       object = cp_build_unary_op (ADDR_EXPR, object, 0, tf_warning_or_error);
-      VEC_safe_insert (tree, gc, *args, 0, object);
+      if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+       {
+         if (TREE_CODE (fn) == DOTSTAR_EXPR)
+           object = cp_build_addr_expr (object, complain);
+         VEC_safe_insert (tree, gc, *args, 0, object);
+       }
       /* Now that the arguments are done, transform FN.  */
       fn = build_non_dependent_expr (fn);
     }
@@ -4017,14 +4131,17 @@ build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args)
        void B::g() { (this->*p)(); }  */
   if (TREE_CODE (fn) == OFFSET_REF)
     {
-      tree object_addr = cp_build_unary_op (ADDR_EXPR, object, 0,
-                                         tf_warning_or_error);
+      tree object_addr = cp_build_addr_expr (object, complain);
       fn = TREE_OPERAND (fn, 1);
-      fn = get_member_function_from_ptrfunc (&object_addr, fn);
+      fn = get_member_function_from_ptrfunc (&object_addr, fn,
+                                            complain);
       VEC_safe_insert (tree, gc, *args, 0, object_addr);
     }
 
-  expr = cp_build_function_call_vec (fn, args, tf_warning_or_error);
+  if (CLASS_TYPE_P (TREE_TYPE (fn)))
+    expr = build_op_call (fn, args, complain);
+  else
+    expr = cp_build_function_call_vec (fn, args, complain);
   if (processing_template_decl && expr != error_mark_node)
     expr = build_min_non_dep_call_vec (expr, orig_fn, orig_args);
 
@@ -4071,22 +4188,21 @@ possibly_inlined_p (tree decl)
 
 /* Mark DECL (either a _DECL or a BASELINK) as "used" in the program.
    If DECL is a specialization or implicitly declared class member,
-   generate the actual definition.  */
+   generate the actual definition.  Return false if something goes
+   wrong, true otherwise.  */
 
-void
+bool
 mark_used (tree decl)
 {
-  HOST_WIDE_INT saved_processing_template_decl = 0;
-
   /* If DECL is a BASELINK for a single function, then treat it just
      like the DECL for the function.  Otherwise, if the BASELINK is
      for an overloaded function, we don't know which function was
      actually used until after overload resolution.  */
-  if (TREE_CODE (decl) == BASELINK)
+  if (BASELINK_P (decl))
     {
       decl = BASELINK_FUNCTIONS (decl);
       if (really_overloaded_fn (decl))
-       return;
+       return true;
       decl = OVL_CURRENT (decl);
     }
 
@@ -4095,6 +4211,10 @@ mark_used (tree decl)
   if (DECL_CLONED_FUNCTION_P (decl))
     TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
 
+  /* Mark enumeration types as used.  */
+  if (TREE_CODE (decl) == CONST_DECL)
+    used_types_insert (DECL_CONTEXT (decl));
+
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DELETED_FN (decl))
     {
@@ -4107,16 +4227,14 @@ mark_used (tree decl)
                 generate it properly; see maybe_add_lambda_conv_op.  */
              sorry ("converting lambda which uses %<...%> to "
                     "function pointer");
-             return;
+             return false;
            }
        }
-      error ("deleted function %q+D", decl);
-      error ("used here");
-      return;
+      error ("use of deleted function %qD", decl);
+      if (!maybe_explain_implicit_delete (decl))
+       error_at (DECL_SOURCE_LOCATION (decl), "declared here");
+      return false;
     }
-  /* If we don't need a value, then we don't need to synthesize DECL.  */
-  if (cp_unevaluated_operand != 0)
-    return;
 
   /* We can only check DECL_ODR_USED on variables or functions with
      DECL_LANG_SPECIFIC set, and these are also the only decls that we
@@ -4124,46 +4242,73 @@ mark_used (tree decl)
   if ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
       || DECL_LANG_SPECIFIC (decl) == NULL
       || DECL_THUNK_P (decl))
-    return;
+    {
+      if (!processing_template_decl && type_uses_auto (TREE_TYPE (decl)))
+       {
+         error ("use of %qD before deduction of %<auto%>", decl);
+         return false;
+       }
+      return true;
+    }
 
   /* We only want to do this processing once.  We don't need to keep trying
      to instantiate inline templates, because unit-at-a-time will make sure
      we get them compiled before functions that want to inline them.  */
   if (DECL_ODR_USED (decl))
-    return;
+    return true;
 
   /* If within finish_function, defer the rest until that function
      finishes, otherwise it might recurse.  */
   if (defer_mark_used_calls)
     {
       VEC_safe_push (tree, gc, deferred_mark_used_calls, decl);
-      return;
+      return true;
     }
 
-  /* Normally, we can wait until instantiation-time to synthesize
-     DECL.  However, if DECL is a static data member initialized with
-     a constant, we need the value right now because a reference to
-     such a data member is not value-dependent.  */
-  if (TREE_CODE (decl) == VAR_DECL
-      && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
-      && DECL_CLASS_SCOPE_P (decl))
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    maybe_instantiate_noexcept (decl);
+
+  /* Normally, we can wait until instantiation-time to synthesize DECL.
+     However, if DECL is a static data member initialized with a constant
+     or a constexpr function, we need it right now because a reference to
+     such a data member or a call to such function is not value-dependent.
+     For a function that uses auto in the return type, we need to instantiate
+     it to find out its type.  */
+  if ((decl_maybe_constant_var_p (decl)
+       || (TREE_CODE (decl) == FUNCTION_DECL
+          && (DECL_DECLARED_CONSTEXPR_P (decl)
+              || type_uses_auto (TREE_TYPE (TREE_TYPE (decl))))))
+      && DECL_LANG_SPECIFIC (decl)
+      && DECL_TEMPLATE_INFO (decl)
+      && !uses_template_parms (DECL_TI_ARGS (decl)))
     {
-      /* Don't try to instantiate members of dependent types.  We
-        cannot just use dependent_type_p here because this function
-        may be called from fold_non_dependent_expr, and then we may
-        see dependent types, even though processing_template_decl
-        will not be set.  */
-      if (CLASSTYPE_TEMPLATE_INFO ((DECL_CONTEXT (decl)))
-         && uses_template_parms (CLASSTYPE_TI_ARGS (DECL_CONTEXT (decl))))
-       return;
-      /* Pretend that we are not in a template, even if we are, so
-        that the static data member initializer will be processed.  */
-      saved_processing_template_decl = processing_template_decl;
-      processing_template_decl = 0;
+      /* Instantiating a function will result in garbage collection.  We
+        must treat this situation as if we were within the body of a
+        function so as to avoid collecting live data only referenced from
+        the stack (such as overload resolution candidates).  */
+      ++function_depth;
+      instantiate_decl (decl, /*defer_ok=*/false,
+                       /*expl_inst_class_mem_p=*/false);
+      --function_depth;
+    }
+
+  if (type_uses_auto (TREE_TYPE (decl)))
+    {
+      error ("use of %qD before deduction of %<auto%>", decl);
+      return false;
     }
 
+  /* If we don't need a value, then we don't need to synthesize DECL.  */
+  if (cp_unevaluated_operand != 0)
+    return true;
+
   if (processing_template_decl)
-    return;
+    return true;
+
+  /* Check this too in case we're within fold_non_dependent_expr.  */
+  if (DECL_TEMPLATE_INFO (decl)
+      && uses_template_parms (DECL_TI_ARGS (decl)))
+    return true;
 
   DECL_ODR_USED (decl) = 1;
   if (DECL_CLONED_FUNCTION_P (decl))
@@ -4198,8 +4343,19 @@ mark_used (tree decl)
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
       && DECL_DEFAULTED_FN (decl)
+      /* A function defaulted outside the class is synthesized either by
+        cp_finish_decl or instantiate_decl.  */
+      && !DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)
       && ! DECL_INITIAL (decl))
     {
+      /* Defer virtual destructors so that thunks get the right
+        linkage.  */
+      if (DECL_VIRTUAL_P (decl) && !at_eof)
+       {
+         note_vague_linkage_fn (decl);
+         return true;
+       }
+
       /* Remember the current location for a function we will end up
         synthesizing.  Then we can inform the user where it was
         required in the case of error.  */
@@ -4211,7 +4367,7 @@ mark_used (tree decl)
         on the stack (such as overload resolution candidates).
 
          We could just let cp_write_global_declarations handle synthesizing
-         this function, since we just added it to deferred_fns, but doing
+         this function by adding it to deferred_fns, but doing
          it at the use site produces better error messages.  */
       ++function_depth;
       synthesize_method (decl);
@@ -4232,10 +4388,14 @@ mark_used (tree decl)
        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,
-                     /*expl_inst_class_mem_p=*/false);
+    {
+      ++function_depth;
+      instantiate_decl (decl, /*defer_ok=*/true,
+                       /*expl_inst_class_mem_p=*/false);
+      --function_depth;
+    }
 
-  processing_template_decl = saved_processing_template_decl;
+  return true;
 }
 
 #include "gt-cp-decl2.h"