OSDN Git Service

* c-cppbuiltin.c (c_cpp_builtins): Change _OPENMP value to
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 5971bb8..8056518 100644 (file)
@@ -1,6 +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, 2006, 2007  Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -356,12 +357,7 @@ pop_label (tree label, tree old_value)
          location_t location;
 
          error ("label %q+D used but not defined", label);
-#ifdef USE_MAPPED_LOCATION
          location = input_location; /* FIXME want (input_filename, (line)0) */
-#else
-         location.file = input_filename;
-         location.line = 0;
-#endif
          /* Avoid crashing later.  */
          define_label (location, DECL_NAME (label));
        }
@@ -587,7 +583,7 @@ poplevel (int keep, int reverse, int functionbody)
 
   /* In each subblock, record that this is its superior.  */
   if (keep >= 0)
-    for (link = subblocks; link; link = TREE_CHAIN (link))
+    for (link = subblocks; link; link = BLOCK_CHAIN (link))
       BLOCK_SUPERCONTEXT (link) = block;
 
   /* We still support the old for-scope rules, whereby the variables
@@ -1280,6 +1276,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type;
        }
 
+      /* If a function is explicitly declared "throw ()", propagate that to
+        the corresponding builtin.  */
+      if (DECL_BUILT_IN_CLASS (olddecl) == BUILT_IN_NORMAL
+         && DECL_ANTICIPATED (olddecl)
+         && TREE_NOTHROW (newdecl)
+         && !TREE_NOTHROW (olddecl)
+         && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != NULL_TREE
+         && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != olddecl
+         && types_match)
+       TREE_NOTHROW (built_in_decls [DECL_FUNCTION_CODE (olddecl)]) = 1;
+
       /* Whether or not the builtin can throw exceptions has no
         bearing on this declarator.  */
       TREE_NOTHROW (olddecl) = 0;
@@ -1663,6 +1670,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
                = DECL_INTERFACE_KNOWN (new_result);
              DECL_DECLARED_INLINE_P (old_result)
                = DECL_DECLARED_INLINE_P (new_result);
+             DECL_DISREGARD_INLINE_LIMITS (old_result)
+               |= DECL_DISREGARD_INLINE_LIMITS (new_result);
+
            }
          else
            {
@@ -1670,6 +1680,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
                |= DECL_INLINE (new_result);
              DECL_DECLARED_INLINE_P (old_result)
                |= DECL_DECLARED_INLINE_P (new_result);
+             DECL_DISREGARD_INLINE_LIMITS (old_result)
+               |= DECL_DISREGARD_INLINE_LIMITS (new_result);
              check_redeclaration_exception_specification (newdecl, olddecl);
            }
        }
@@ -1790,10 +1802,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
            |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
          DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
          TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
-         TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
          TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl);
          DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
-         DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
+         DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
+         DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl);
+         TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
+         DECL_LOOPING_CONST_OR_PURE_P (newdecl) 
+           |= DECL_LOOPING_CONST_OR_PURE_P (olddecl);
          /* Keep the old RTL.  */
          COPY_DECL_RTL (olddecl, newdecl);
        }
@@ -1835,24 +1850,24 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
   new_template = NULL_TREE;
   if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
     {
-      bool old_decl_gnu_inline;
+      bool new_redefines_gnu_inline = false;
 
-      if ((DECL_INTERFACE_KNOWN (olddecl)
-          && TREE_CODE (olddecl) == FUNCTION_DECL)
-         || (TREE_CODE (olddecl) == TEMPLATE_DECL
-             && TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL))
+      if (new_defines_function
+         && ((DECL_INTERFACE_KNOWN (olddecl)
+              && TREE_CODE (olddecl) == FUNCTION_DECL)
+             || (TREE_CODE (olddecl) == TEMPLATE_DECL
+                 && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))
+                     == FUNCTION_DECL))))
        {
          tree fn = olddecl;
 
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            fn = DECL_TEMPLATE_RESULT (olddecl);
 
-         old_decl_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn);
+         new_redefines_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn);
        }
-      else
-       old_decl_gnu_inline = false;
 
-      if (!old_decl_gnu_inline)
+      if (!new_redefines_gnu_inline)
        {
          DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
          DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
@@ -2878,7 +2893,7 @@ build_typename_type (tree context, tree name, tree fullname,
   else
     {
       /* Build the TYPENAME_TYPE.  */
-      t = make_aggr_type (TYPENAME_TYPE);
+      t = cxx_make_type (TYPENAME_TYPE);
       TYPE_CONTEXT (t) = ti.scope;
       TYPENAME_TYPE_FULLNAME (t) = ti.template_id;
       TYPENAME_IS_ENUM_P (t) = ti.enum_p;
@@ -2966,7 +2981,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   if (dependent_type_p (context))
     return build_typename_type (context, name, fullname, tag_type);
 
-  if (!IS_AGGR_TYPE (context))
+  if (!MAYBE_CLASS_TYPE_P (context))
     {
       if (complain & tf_error)
        error ("%q#T is not a class", context);
@@ -3043,7 +3058,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
     {
       tree tmpl = NULL_TREE;
 
-      if (IS_AGGR_TYPE (context))
+      if (MAYBE_CLASS_TYPE_P (context))
        tmpl = lookup_field (context, name, 0, false);
 
       if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
@@ -3071,7 +3086,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
     }
 
   /* Build the UNBOUND_CLASS_TEMPLATE.  */
-  t = make_aggr_type (UNBOUND_CLASS_TEMPLATE);
+  t = cxx_make_type (UNBOUND_CLASS_TEMPLATE);
   TYPE_CONTEXT (t) = FROB_CONTEXT (context);
   TREE_TYPE (t) = NULL_TREE;
   SET_TYPE_STRUCTURAL_EQUALITY (t);
@@ -3369,7 +3384,7 @@ cxx_init_decl_processing (void)
 
     push_namespace (std_identifier);
     bad_alloc_id = get_identifier ("bad_alloc");
-    bad_alloc_type_node = make_aggr_type (RECORD_TYPE);
+    bad_alloc_type_node = make_class_type (RECORD_TYPE);
     TYPE_CONTEXT (bad_alloc_type_node) = current_namespace;
     bad_alloc_decl
       = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);
@@ -3517,6 +3532,17 @@ builtin_function_1 (tree decl, tree context)
      anticipated but not actually declared.  */
   if (name[0] != '_' || name[1] != '_')
     DECL_ANTICIPATED (decl) = 1;
+  else if (strncmp (name + 2, "builtin_", strlen ("builtin_")) != 0)
+    {
+      size_t len = strlen (name);
+
+      /* Treat __*_chk fortification functions as anticipated as well,
+        unless they are __builtin_*.  */
+      if (len > strlen ("___chk")
+         && memcmp (name + len - strlen ("_chk"),
+                    "_chk", strlen ("_chk") + 1) == 0)
+       DECL_ANTICIPATED (decl) = 1;
+    }
 
   return decl;
 }
@@ -3662,7 +3688,7 @@ fixup_anonymous_aggr (tree t)
   tree *q;
 
   /* Wipe out memory of synthesized methods.  */
-  TYPE_HAS_CONSTRUCTOR (t) = 0;
+  TYPE_HAS_USER_CONSTRUCTOR (t) = 0;
   TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0;
   TYPE_HAS_INIT_REF (t) = 0;
   TYPE_HAS_CONST_INIT_REF (t) = 0;
@@ -3682,8 +3708,14 @@ fixup_anonymous_aggr (tree t)
 
   /* ISO C++ 9.5.3.  Anonymous unions may not have function members.  */
   if (TYPE_METHODS (t))
-    error ("%Jan anonymous union cannot have function members",
-          TYPE_MAIN_DECL (t));
+    {
+      tree decl = TYPE_MAIN_DECL (t);
+
+      if (TREE_CODE (t) != UNION_TYPE)
+       error ("%Jan anonymous struct cannot have function members", decl);
+      else
+       error ("%Jan anonymous union cannot have function members", decl);
+    }
 
   /* Anonymous aggregates cannot have fields with ctors, dtors or complex
      assignment operators (because they cannot have these methods themselves).
@@ -3743,7 +3775,7 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
   if (declspecs->type
       && TYPE_P (declspecs->type)
       && ((TREE_CODE (declspecs->type) != TYPENAME_TYPE
-          && IS_AGGR_TYPE (declspecs->type))
+          && MAYBE_CLASS_TYPE_P (declspecs->type))
          || TREE_CODE (declspecs->type) == ENUMERAL_TYPE))
     declared_type = declspecs->type;
   else if (declspecs->type == error_mark_node)
@@ -3751,7 +3783,7 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
   if (declared_type == NULL_TREE && ! saw_friend && !error_p)
     pedwarn ("declaration does not declare anything");
   /* Check for an anonymous union.  */
-  else if (declared_type && IS_AGGR_TYPE_CODE (TREE_CODE (declared_type))
+  else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type))
           && TYPE_ANONYMOUS_P (declared_type))
     {
       /* 7/3 In a simple-declaration, the optional init-declarator-list
@@ -3875,31 +3907,35 @@ groktypename (cp_decl_specifier_seq *type_specifiers,
   attrs = type_specifiers->attributes;
   type_specifiers->attributes = NULL_TREE;
   type = grokdeclarator (declarator, type_specifiers, TYPENAME, 0, &attrs);
-  if (attrs)
+  if (attrs && type != error_mark_node)
     {
       if (CLASS_TYPE_P (type))
-       warning (OPT_Wattributes, "ignoring attributes applied to class type "
-                "outside of definition");
+       warning (OPT_Wattributes, "ignoring attributes applied to class type %qT "
+                "outside of definition", type);
+      else if (MAYBE_CLASS_TYPE_P (type))
+       /* A template type parameter or other dependent type.  */
+       warning (OPT_Wattributes, "ignoring attributes applied to dependent "
+                "type %qT without an associated declaration", type);
       else
        cplus_decl_attributes (&type, attrs, 0);
     }
   return type;
 }
 
-/* Decode a declarator in an ordinary declaration or data definition.
-   This is called as soon as the type information and variable name
-   have been parsed, before parsing the initializer if any.
-   Here we create the ..._DECL node, fill in its type,
-   and put it on the list of decls for the current context.
-   The ..._DECL node is returned as the value.
-
-   Exception: for arrays where the length is not specified,
-   the type is left null, to be filled in by `cp_finish_decl'.
-
-   Function definitions do not come here; they go to start_function
-   instead.  However, external and forward declarations of functions
-   do go through here.  Structure field declarations are done by
-   grokfield and not through here.  */
+/* Process a DECLARATOR for a function-scope variable declaration,
+   namespace-scope variable declaration, or function declaration.
+   (Function definitions go through start_function; class member
+   declarations appearing in the body of the class go through
+   grokfield.)  The DECL corresponding to the DECLARATOR is returned.
+   If an error occurs, the error_mark_node is returned instead.
+   
+   DECLSPECS are the decl-specifiers for the declaration.  INITIALIZED
+   is true if an explicit initializer is present, but false if this is
+   a variable implicitly initialized via a default constructor.
+   ATTRIBUTES and PREFIX_ATTRIBUTES are GNU attributes associated with
+   this declaration.  *PUSHED_SCOPE_P is set to the scope entered in
+   this function, if any; if set, the caller is responsible for
+   calling pop_scope.  */
 
 tree
 start_decl (const cp_declarator *declarator,
@@ -3910,9 +3946,10 @@ start_decl (const cp_declarator *declarator,
            tree *pushed_scope_p)
 {
   tree decl;
-  tree type, tem;
+  tree type;
   tree context;
   bool was_public;
+  int flags;
 
   *pushed_scope_p = NULL_TREE;
 
@@ -3974,8 +4011,17 @@ start_decl (const cp_declarator *declarator,
        TREE_STATIC (decl) = 1;
     }
 
+  /* If this is a typedef that names the class for linkage purposes
+     (7.1.3p8), apply any attributes directly to the type.  */
+  if (TREE_CODE (decl) == TYPE_DECL
+      && TAGGED_TYPE_P (TREE_TYPE (decl))
+      && decl == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))))
+    flags = ATTR_FLAG_TYPE_IN_PLACE;
+  else
+    flags = 0;
+
   /* Set attributes here so if duplicate decl, will have proper attributes.  */
-  cplus_decl_attributes (&decl, attributes, 0);
+  cplus_decl_attributes (&decl, attributes, flags);
 
   /* Dllimported symbols cannot be defined.  Static data members (which
      can be initialized in-class and dllimported) go through grokfield,
@@ -4071,11 +4117,11 @@ start_decl (const cp_declarator *declarator,
   was_public = TREE_PUBLIC (decl);
 
   /* Enter this declaration into the symbol table.  */
-  tem = maybe_push_decl (decl);
+  decl = maybe_push_decl (decl);
 
   if (processing_template_decl)
-    tem = push_template_decl (tem);
-  if (tem == error_mark_node)
+    decl = push_template_decl (decl);
+  if (decl == error_mark_node)
     return error_mark_node;
 
   /* Tell the back end to use or not use .common as appropriate.  If we say
@@ -4084,33 +4130,42 @@ start_decl (const cp_declarator *declarator,
      produce errors about redefs; to do this we force variables into the
      data segment.  */
   if (flag_conserve_space
-      && TREE_CODE (tem) == VAR_DECL
-      && TREE_PUBLIC (tem)
-      && !DECL_THREAD_LOCAL_P (tem)
+      && TREE_CODE (decl) == VAR_DECL
+      && TREE_PUBLIC (decl)
+      && !DECL_THREAD_LOCAL_P (decl)
       && !have_global_bss_p ())
-    DECL_COMMON (tem) = 1;
+    DECL_COMMON (decl) = 1;
 
-  if (TREE_CODE (tem) == VAR_DECL
-      && DECL_NAMESPACE_SCOPE_P (tem) && !TREE_PUBLIC (tem) && !was_public
-      && !DECL_THIS_STATIC (tem) && !DECL_ARTIFICIAL (tem))
+  if (TREE_CODE (decl) == VAR_DECL
+      && DECL_NAMESPACE_SCOPE_P (decl) && !TREE_PUBLIC (decl) && !was_public
+      && !DECL_THIS_STATIC (decl) && !DECL_ARTIFICIAL (decl))
     {
       /* This is a const variable with implicit 'static'.  Set
         DECL_THIS_STATIC so we can tell it from variables that are
         !TREE_PUBLIC because of the anonymous namespace.  */
-      gcc_assert (cp_type_readonly (TREE_TYPE (tem)));
-      DECL_THIS_STATIC (tem) = 1;
+      gcc_assert (cp_type_readonly (TREE_TYPE (decl)));
+      DECL_THIS_STATIC (decl) = 1;
     }
 
-  if (!processing_template_decl && TREE_CODE (tem) == VAR_DECL)
-    start_decl_1 (tem, initialized);
+  if (!processing_template_decl && TREE_CODE (decl) == VAR_DECL)
+    start_decl_1 (decl, initialized);
 
-  return tem;
+  return decl;
 }
 
+/* Process the declaration of a variable DECL.  INITIALIZED is true
+   iff DECL is explicitly initialized.  (INITIALIZED is false if the
+   variable is initialized via an implicitly-called constructor.)
+   This function must be called for ordinary variables (including, for
+   example, implicit instantiations of templates), but must not be
+   called for template declarations.  */
+
 void
 start_decl_1 (tree decl, bool initialized)
 {
   tree type;
+  bool complete_p;
+  bool aggregate_definition_p;
 
   gcc_assert (!processing_template_decl);
 
@@ -4118,21 +4173,37 @@ start_decl_1 (tree decl, bool initialized)
     return;
 
   gcc_assert (TREE_CODE (decl) == VAR_DECL);
+
   type = TREE_TYPE (decl);
+  complete_p = COMPLETE_TYPE_P (type);
+  aggregate_definition_p = MAYBE_CLASS_TYPE_P (type) && !DECL_EXTERNAL (decl);
+
+  /* If an explicit initializer is present, or if this is a definition
+     of an aggregate, then we need a complete type at this point.
+     (Scalars are always complete types, so there is nothing to
+     check.)  This code just sets COMPLETE_P; errors (if necessary)
+     are issued below.  */
+  if ((initialized || aggregate_definition_p) 
+      && !complete_p
+      && COMPLETE_TYPE_P (complete_type (type)))
+    {
+      complete_p = true;
+      /* We will not yet have set TREE_READONLY on DECL if the type
+        was "const", but incomplete, before this point.  But, now, we
+        have a complete type, so we can try again.  */
+      cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
+    }
 
   if (initialized)
-    /* Is it valid for this decl to have an initializer at all?
-       If not, set INITIALIZED to zero, which will indirectly
-       tell `cp_finish_decl' to ignore the initializer once it is parsed.  */
+    /* Is it valid for this decl to have an initializer at all?  */
     {
       /* Don't allow initializations for incomplete types except for
         arrays which might be completed by the initialization.  */
-      if (COMPLETE_TYPE_P (complete_type (type)))
+      if (complete_p)
        ;                       /* A complete type is ok.  */
       else if (TREE_CODE (type) != ARRAY_TYPE)
        {
          error ("variable %q#D has initializer but incomplete type", decl);
-         initialized = 0;
          type = TREE_TYPE (decl) = error_mark_node;
        }
       else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
@@ -4140,30 +4211,15 @@ start_decl_1 (tree decl, bool initialized)
          if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
            error ("elements of array %q#D have incomplete type", decl);
          /* else we already gave an error in start_decl.  */
-         initialized = 0;
        }
     }
-  else if (IS_AGGR_TYPE (type)
-          && ! DECL_EXTERNAL (decl))
+  else if (aggregate_definition_p && !complete_p)
     {
-      if (!COMPLETE_TYPE_P (complete_type (type)))
-       {
-         error ("aggregate %q#D has incomplete type and cannot be defined",
-                decl);
-         /* Change the type so that assemble_variable will give
-            DECL an rtl we can live with: (mem (const_int 0)).  */
-         type = TREE_TYPE (decl) = error_mark_node;
-       }
-      else
-       {
-         /* If any base type in the hierarchy of TYPE needs a constructor,
-            then we set initialized to 1.  This way any nodes which are
-            created for the purposes of initializing this aggregate
-            will live as long as it does.  This is necessary for global
-            aggregates which do not have their initializers processed until
-            the end of the file.  */
-         initialized = TYPE_NEEDS_CONSTRUCTING (type);
-       }
+      error ("aggregate %q#D has incomplete type and cannot be defined",
+            decl);
+      /* Change the type so that assemble_variable will give
+        DECL an rtl we can live with: (mem (const_int 0)).  */
+      type = TREE_TYPE (decl) = error_mark_node;
     }
 
   /* Create a new scope to hold this declaration if necessary.
@@ -4293,7 +4349,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
          HOST_WIDE_INT i;
          for (i = 0; 
               VEC_iterate (constructor_elt, v, i, ce);
-              ++i)
+              ++i) 
            if (!check_array_designated_initializer (ce))
              failure = 1;
        }
@@ -4373,7 +4429,7 @@ layout_var_decl (tree decl)
   /* Keep this code around in case we later want to control debug info
      based on whether a type is "used".  (jason 1999-11-11) */
 
-  else if (!DECL_EXTERNAL (decl) && IS_AGGR_TYPE (ttype))
+  else if (!DECL_EXTERNAL (decl) && MAYBE_CLASS_TYPE_P (ttype))
     /* Let debugger know it should output info for this type.  */
     note_debug_info_needed (ttype);
 
@@ -4388,7 +4444,10 @@ layout_var_decl (tree decl)
       if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
        constant_expression_warning (DECL_SIZE (decl));
       else
-       error ("storage size of %qD isn't constant", decl);
+       {
+         error ("storage size of %qD isn't constant", decl);
+         TREE_TYPE (decl) = error_mark_node;
+       }
     }
 }
 
@@ -4835,6 +4894,38 @@ reshape_init (tree type, tree init)
   return new_init;
 }
 
+/* Verify array initializer.  Returns true if errors have been reported.  */
+
+bool
+check_array_initializer (tree decl, tree type, tree init)
+{
+  tree element_type = TREE_TYPE (type);
+
+  /* The array type itself need not be complete, because the
+     initializer may tell us how many elements are in the array.
+     But, the elements of the array must be complete.  */
+  if (!COMPLETE_TYPE_P (complete_type (element_type)))
+    {
+      if (decl)
+       error ("elements of array %q#D have incomplete type", decl);
+      else
+       error ("elements of array %q#T have incomplete type", type);
+      return true;
+    }
+  /* It is not valid to initialize a VLA.  */
+  if (init
+      && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
+         || !TREE_CONSTANT (TYPE_SIZE (element_type))))
+    {
+      if (decl)
+       error ("variable-sized object %qD may not be initialized", decl);
+      else
+       error ("variable-sized compound literal");
+      return true;
+    }
+  return false;
+}
+
 /* Verify INIT (the initializer for DECL), and record the
    initialization in DECL_INITIAL, if appropriate.  CLEANUP is as for
    grok_reference_init.
@@ -4858,24 +4949,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
 
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
-      tree element_type = TREE_TYPE (type);
-
-      /* The array type itself need not be complete, because the
-        initializer may tell us how many elements are in the array.
-        But, the elements of the array must be complete.  */
-      if (!COMPLETE_TYPE_P (complete_type (element_type)))
-       {
-         error ("elements of array %q#D have incomplete type", decl);
-         return NULL_TREE;
-       }
-      /* It is not valid to initialize a VLA.  */
-      if (init
-         && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
-             || !TREE_CONSTANT (TYPE_SIZE (element_type))))
-       {
-         error ("variable-sized object %qD may not be initialized", decl);
-         return NULL_TREE;
-       }
+      if (check_array_initializer (decl, type, init))
+       return NULL_TREE;
     }
   else if (!COMPLETE_TYPE_P (type))
     {
@@ -4946,11 +5021,11 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
       if (type == error_mark_node)
        return NULL_TREE;
 
-      if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
+      if (TREE_CODE (type) == ARRAY_TYPE && TYPE_NEEDS_CONSTRUCTING (type))
+       goto initialize_aggr;
+      else if (CLASS_TYPE_P (type))
        {
-         if (TREE_CODE (type) == ARRAY_TYPE)
-           goto initialize_aggr;
-         else if (TREE_CODE (init) == CONSTRUCTOR)
+         if (TREE_CODE (init) == CONSTRUCTOR)
            {
              if (TYPE_NON_AGGREGATE_CLASS (type))
                {
@@ -4973,7 +5048,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
                  saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
                  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
                }
-             init = build_aggr_init (decl, init, flags);
+             init = build_aggr_init (decl, init, flags, tf_warning_or_error);
              if (building_stmt_tree ())
                current_stmt_tree ()->stmts_are_full_exprs_p =
                  saved_stmts_are_full_exprs_p;
@@ -5000,7 +5075,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
     ;
   else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type))
     goto initialize_aggr;
-  else if (IS_AGGR_TYPE (type))
+  else if (MAYBE_CLASS_TYPE_P (type))
     {
       tree core_type = strip_array_types (type);
 
@@ -5064,7 +5139,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
       /* An in-class declaration of a static data member should be
         external; it is only a declaration, and not a definition.  */
       if (init == NULL_TREE)
-       gcc_assert (DECL_EXTERNAL (decl));
+       gcc_assert (DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl));
     }
 
   /* We don't create any RTL for local variables.  */
@@ -5108,6 +5183,55 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
     rest_of_decl_compilation (decl, toplev, at_eof);
 }
 
+/* walk_tree helper for wrap_temporary_cleanups, below.  */
+
+static tree
+wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data)
+{
+  if (TYPE_P (*stmt_p))
+    {
+      *walk_subtrees = 0;
+      return NULL_TREE;
+    }
+
+  if (TREE_CODE (*stmt_p) == TARGET_EXPR)
+    {
+      tree guard = (tree)data;
+      tree tcleanup = TARGET_EXPR_CLEANUP (*stmt_p);
+
+      tcleanup = build2 (TRY_CATCH_EXPR, void_type_node, tcleanup, guard);
+      /* Tell honor_protect_cleanup_actions to handle this as a separate
+        cleanup.  */
+      TRY_CATCH_IS_CLEANUP (tcleanup) = 1;
+      TARGET_EXPR_CLEANUP (*stmt_p) = tcleanup;
+    }
+
+  return NULL_TREE;
+}
+
+/* We're initializing a local variable which has a cleanup GUARD.  If there
+   are any temporaries used in the initializer INIT of this variable, we
+   need to wrap their cleanups with TRY_CATCH_EXPR (, GUARD) so that the
+   variable will be cleaned up properly if one of them throws.
+
+   Unfortunately, there's no way to express this properly in terms of
+   nesting, as the regions for the temporaries overlap the region for the
+   variable itself; if there are two temporaries, the variable needs to be
+   the first thing destroyed if either of them throws.  However, we only
+   want to run the variable's cleanup if it actually got constructed.  So
+   we need to guard the temporary cleanups with the variable's cleanup if
+   they are run on the normal path, but not if they are run on the
+   exceptional path.  We implement this by telling
+   honor_protect_cleanup_actions to strip the variable cleanup from the
+   exceptional path.  */
+
+static void
+wrap_temporary_cleanups (tree init, tree guard)
+{
+  cp_walk_tree_without_duplicates (&init, wrap_cleanups_r, (void *)guard);
+}
+
 /* Generate code to initialize DECL (a local variable).  */
 
 static void
@@ -5115,6 +5239,7 @@ initialize_local_var (tree decl, tree init)
 {
   tree type = TREE_TYPE (decl);
   tree cleanup;
+  int already_used;
 
   gcc_assert (TREE_CODE (decl) == VAR_DECL
              || TREE_CODE (decl) == RESULT_DECL);
@@ -5125,46 +5250,53 @@ initialize_local_var (tree decl, tree init)
       /* If we used it already as memory, it must stay in memory.  */
       DECL_INITIAL (decl) = NULL_TREE;
       TREE_ADDRESSABLE (decl) = TREE_USED (decl);
+      return;
     }
 
-  if (DECL_SIZE (decl) && type != error_mark_node)
-    {
-      int already_used;
+  if (type == error_mark_node)
+    return;
 
-      /* Compute and store the initial value.  */
-      already_used = TREE_USED (decl) || TREE_USED (type);
+  /* Compute and store the initial value.  */
+  already_used = TREE_USED (decl) || TREE_USED (type);
 
-      /* Perform the initialization.  */
-      if (init)
-       {
-         int saved_stmts_are_full_exprs_p;
+  /* Generate a cleanup, if necessary.  */
+  cleanup = cxx_maybe_build_cleanup (decl);
 
-         gcc_assert (building_stmt_tree ());
-         saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
-         current_stmt_tree ()->stmts_are_full_exprs_p = 1;
-         finish_expr_stmt (init);
-         current_stmt_tree ()->stmts_are_full_exprs_p =
-           saved_stmts_are_full_exprs_p;
-       }
+  /* Perform the initialization.  */
+  if (init)
+    {
+      int saved_stmts_are_full_exprs_p;
 
-      /* Set this to 0 so we can tell whether an aggregate which was
-        initialized was ever used.  Don't do this if it has a
-        destructor, so we don't complain about the 'resource
-        allocation is initialization' idiom.  Now set
-        attribute((unused)) on types so decls of that type will be
-        marked used. (see TREE_USED, above.)  */
-      if (TYPE_NEEDS_CONSTRUCTING (type)
-         && ! already_used
-         && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)
-         && DECL_NAME (decl))
-       TREE_USED (decl) = 0;
-      else if (already_used)
-       TREE_USED (decl) = 1;
-    }
+      /* If we're only initializing a single object, guard the destructors
+        of any temporaries used in its initializer with its destructor.
+        This isn't right for arrays because each element initialization is
+        a full-expression.  */
+      if (cleanup && TREE_CODE (type) != ARRAY_TYPE)
+       wrap_temporary_cleanups (init, cleanup);
 
-  /* Generate a cleanup, if necessary.  */
-  cleanup = cxx_maybe_build_cleanup (decl);
-  if (DECL_SIZE (decl) && cleanup)
+      gcc_assert (building_stmt_tree ());
+      saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+      current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+      finish_expr_stmt (init);
+      current_stmt_tree ()->stmts_are_full_exprs_p =
+       saved_stmts_are_full_exprs_p;
+    }
+
+  /* Set this to 0 so we can tell whether an aggregate which was
+     initialized was ever used.  Don't do this if it has a
+     destructor, so we don't complain about the 'resource
+     allocation is initialization' idiom.  Now set
+     attribute((unused)) on types so decls of that type will be
+     marked used. (see TREE_USED, above.)  */
+  if (TYPE_NEEDS_CONSTRUCTING (type)
+      && ! already_used
+      && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)
+      && DECL_NAME (decl))
+    TREE_USED (decl) = 0;
+  else if (already_used)
+    TREE_USED (decl) = 1;
+
+  if (cleanup)
     finish_decl_cleanup (decl, cleanup);
 }
 
@@ -5284,6 +5416,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 
       type_dependent_p = dependent_type_p (type);
 
+      if (check_for_bare_parameter_packs (init))
+       {
+         init = NULL_TREE;
+         DECL_INITIAL (decl) = NULL_TREE;
+       }
+
       if (init && init_const_expr_p)
        {
          DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
@@ -5311,7 +5449,21 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          goto finish_end;
        }
 
-      init = fold_non_dependent_expr (init);
+      if (TREE_CODE (init) == TREE_LIST)
+       {
+         /* If the parenthesized-initializer form was used (e.g.,
+            "int A<N>::i(X)"), then INIT will be a TREE_LIST of initializer
+            arguments.  (There is generally only one.)  We convert them
+            individually.  */
+         tree list = init;
+         for (; list; list = TREE_CHAIN (list))
+           {
+             tree elt = TREE_VALUE (list);
+             TREE_VALUE (list) = fold_non_dependent_expr (elt);
+           }
+       }
+      else
+       init = fold_non_dependent_expr (init);
       processing_template_decl = 0;
     }
 
@@ -5319,7 +5471,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (TREE_CODE (decl) == TYPE_DECL)
     {
       if (type != error_mark_node
-         && IS_AGGR_TYPE (type) && DECL_NAME (decl))
+         && MAYBE_CLASS_TYPE_P (type) && DECL_NAME (decl))
        {
          if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
            warning (0, "shadowing previous type declaration of %q#D", decl);
@@ -5360,8 +5512,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
         require a guard variable, and since the mangled name of the
         guard variable will depend on the mangled name of this
         variable.  */
-      if (!processing_template_decl
-         && DECL_FUNCTION_SCOPE_P (decl)
+      if (DECL_FUNCTION_SCOPE_P (decl)
          && TREE_STATIC (decl)
          && !DECL_ARTIFICIAL (decl))
        push_local_name (decl);
@@ -5374,6 +5525,20 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
             is *not* defined.  */
          && (!DECL_EXTERNAL (decl) || init))
        {
+         if (TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
+           {
+             tree jclass
+               = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jclass"));
+             /* Allow libjava/prims.cc define primitive classes.  */
+             if (init != NULL_TREE
+                 || jclass == NULL_TREE
+                 || TREE_CODE (jclass) != TYPE_DECL
+                 || !POINTER_TYPE_P (TREE_TYPE (jclass))
+                 || !same_type_ignoring_top_level_qualifiers_p
+                                       (type, TREE_TYPE (TREE_TYPE (jclass))))
+               error ("Java object %qD not allocated with %<new%>", decl);
+             init = NULL_TREE;
+           }
          if (init)
            {
              DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
@@ -5444,6 +5609,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       else if (TREE_CODE (type) == ARRAY_TYPE)
        layout_type (type);
     }
+  else if (TREE_CODE (decl) == FIELD_DECL
+          && TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
+    error ("non-static data member %qD has Java class type", decl);
 
   /* Add this declaration to the statement-tree.  This needs to happen
      after the call to check_initializer so that the DECL_EXPR for a
@@ -5466,6 +5634,21 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       /* This needs to happen after the linkage is set. */
       determine_visibility (decl);
 
+      if (var_definition_p && TREE_STATIC (decl))
+       {
+         /* If a TREE_READONLY variable needs initialization
+            at runtime, it is no longer readonly and we need to
+            avoid MEM_READONLY_P being set on RTL created for it.  */
+         if (init)
+           {
+             if (TREE_READONLY (decl))
+               TREE_READONLY (decl) = 0;
+             was_readonly = 0;
+           }
+         else if (was_readonly)
+           TREE_READONLY (decl) = 1;
+       }
+
       make_rtl_for_nonlocal_decl (decl, init, asmspec);
 
       /* Check for abstractness of the type. Notice that there is no
@@ -5488,40 +5671,21 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          if (init)
            DECL_INITIAL (decl) = init;
        }
-      else
-       {
-         /* A variable definition.  */
-         if (DECL_FUNCTION_SCOPE_P (decl))
-           {
-             /* Initialize the local variable.  */
-             if (processing_template_decl)
-               DECL_INITIAL (decl) = init;
-             else if (!TREE_STATIC (decl))
-               initialize_local_var (decl, init);
-           }
+      /* A variable definition.  */
+      else if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl))
+       /* Initialize the local variable.  */
+       initialize_local_var (decl, init);
 
-         /* If a variable is defined, and then a subsequent
-            definition with external linkage is encountered, we will
-            get here twice for the same variable.  We want to avoid
-            calling expand_static_init more than once.  For variables
-            that are not static data members, we can call
-            expand_static_init only when we actually process the
-            initializer.  It is not legal to redeclare a static data
-            member, so this issue does not arise in that case.  */
-         if (var_definition_p && TREE_STATIC (decl))
-           {
-             /* If a TREE_READONLY variable needs initialization
-                at runtime, it is no longer readonly and we need to
-                avoid MEM_READONLY_P being set on RTL created for it.  */
-             if (init)
-               {
-                 if (TREE_READONLY (decl))
-                   TREE_READONLY (decl) = 0;
-                 was_readonly = 0;
-               }
-             expand_static_init (decl, init);
-           }
-       }
+      /* If a variable is defined, and then a subsequent
+        definition with external linkage is encountered, we will
+        get here twice for the same variable.  We want to avoid
+        calling expand_static_init more than once.  For variables
+        that are not static data members, we can call
+        expand_static_init only when we actually process the
+        initializer.  It is not legal to redeclare a static data
+        member, so this issue does not arise in that case.  */
+      else if (var_definition_p && TREE_STATIC (decl))
+       expand_static_init (decl, init);
     }
 
   /* If a CLEANUP_STMT was created to destroy a temporary bound to a
@@ -5835,7 +5999,7 @@ register_dtor_fn (tree decl)
          addr = build_address (decl);
          /* The declared type of the parameter to "__cxa_atexit" is
             "void *".  For plain "T*", we could just let the
-            machinery in build_function_call convert it -- but if the
+            machinery in cp_build_function_call convert it -- but if the
             type is "cv-qualified T *", then we need to convert it
             before passing it in, to avoid spurious errors.  */
          addr = build_nop (ptr_type_node, addr);
@@ -5847,7 +6011,8 @@ register_dtor_fn (tree decl)
           other value.  */
        addr = null_pointer_node;
       args = tree_cons (NULL_TREE,
-                       build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0),
+                       cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0,
+                                        tf_warning_or_error),
                        NULL_TREE);
       if (targetm.cxx.use_aeabi_atexit ())
        {
@@ -5862,7 +6027,8 @@ register_dtor_fn (tree decl)
     }
   else
     args = tree_cons (NULL_TREE, cleanup, NULL_TREE);
-  return build_function_call (get_atexit_node (), args);
+  return cp_build_function_call (get_atexit_node (), args, 
+                                tf_warning_or_error);
 }
 
 /* DECL is a VAR_DECL with static storage duration.  INIT, if present,
@@ -6020,6 +6186,9 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
 
   if (initial_value)
     {
+      unsigned HOST_WIDE_INT i;
+      tree value;
+
       /* An array of character type can be initialized from a
         brace-enclosed string constant.
 
@@ -6036,6 +6205,18 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
              && VEC_length (constructor_elt, v) == 1)
            initial_value = value;
        }
+
+      /* If any of the elements are parameter packs, we can't actually
+        complete this type now because the array size is dependent.  */
+      if (TREE_CODE (initial_value) == CONSTRUCTOR)
+       {
+         FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (initial_value), 
+                                     i, value)
+           {
+             if (PACK_EXPANSION_P (value))
+               return 0;
+           }
+       }
     }
 
   failure = complete_array_type (ptype, initial_value, do_default);
@@ -6492,7 +6673,10 @@ grokfndecl (tree ctype,
               XXX Isn't this done in start_function, too?  */
            revert_static_member_fn (decl);
          if (DECL_ARTIFICIAL (old_decl))
-           error ("definition of implicitly-declared %qD", old_decl);
+           {
+             error ("definition of implicitly-declared %qD", old_decl);
+             return NULL_TREE;
+           }
 
          /* Since we've smashed OLD_DECL to its
             DECL_TEMPLATE_RESULT, we must do the same to DECL.  */
@@ -6693,13 +6877,13 @@ build_ptrmemfunc_type (tree type)
     unqualified_variant
       = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
 
-  t = make_aggr_type (RECORD_TYPE);
+  t = make_class_type (RECORD_TYPE);
   xref_basetypes (t, NULL_TREE);
 
   /* Let the front end know this is a pointer to member function...  */
   TYPE_PTRMEMFUNC_FLAG (t) = 1;
-  /* ... and not really an aggregate.  */
-  SET_IS_AGGR_TYPE (t, 0);
+  /* ... and not really a class type.  */
+  SET_CLASS_TYPE_P (t, 0);
 
   field = build_decl (FIELD_DECL, pfn_identifier, type);
   fields = field;
@@ -6858,12 +7042,7 @@ compute_array_index_type (tree name, tree size)
     {
       /* Check to see if the array bound overflowed.  Make that an
         error, no matter how generous we're being.  */
-      int old_flag_pedantic_errors = flag_pedantic_errors;
-      int old_pedantic = pedantic;
-      pedantic = flag_pedantic_errors = 1;
-      constant_expression_warning (size);
-      pedantic = old_pedantic;
-      flag_pedantic_errors = old_flag_pedantic_errors;
+      constant_expression_error (size);
 
       /* An array must have a positive number of elements.  */
       if (INT_CST_LT (size, integer_zero_node))
@@ -6926,7 +7105,8 @@ compute_array_index_type (tree name, tree size)
       processing_template_decl = 0;
       itype = cp_build_binary_op (MINUS_EXPR,
                                  cp_convert (ssizetype, size),
-                                 cp_convert (ssizetype, integer_one_node));
+                                 cp_convert (ssizetype, integer_one_node),
+                                 tf_warning_or_error);
       itype = fold (itype);
       processing_template_decl = saved_processing_template_decl;
 
@@ -7454,6 +7634,12 @@ grokdeclarator (const cp_declarator *declarator,
       return error_mark_node;
     }
 
+  if (declspecs->conflicting_specifiers_p)
+    {
+      error ("conflicting specifiers in declaration of %qs", name);
+      return error_mark_node;
+    }
+
   /* Extract the basic type from the decl-specifier-seq.  */
   type = declspecs->type;
   if (type == error_mark_node)
@@ -7470,6 +7656,10 @@ grokdeclarator (const cp_declarator *declarator,
     {
       typedef_decl = type;
       type = TREE_TYPE (typedef_decl);
+      if (TREE_DEPRECATED (type)
+         && DECL_ARTIFICIAL (typedef_decl)
+         && deprecated_state != DEPRECATED_SUPPRESS)
+       warn_deprecated_use (type);
     }
   /* No type at all: default to `int', and set DEFAULTED_INT
      because it was not a user-defined typedef.  */
@@ -7560,6 +7750,13 @@ grokdeclarator (const cp_declarator *declarator,
        error ("%<long%> or %<short%> specified with char for %qs", name);
       else if (long_p && short_p)
        error ("%<long%> and %<short%> specified together for %qs", name);
+      else if (type == char16_type_node || type == char32_type_node)
+       {
+         if (signed_p || unsigned_p)
+           error ("%<signed%> or %<unsigned%> invalid for %qs", name);
+         else if (short_p || long_p)
+           error ("%<short%> or %<long%> invalid for %qs", name);
+       }
       else
        {
          ok = 1;
@@ -7723,7 +7920,7 @@ grokdeclarator (const cp_declarator *declarator,
   if (virtualp
       && (current_class_name == NULL_TREE || decl_context != FIELD))
     {
-      error ("virtual outside class declaration");
+      error ("%<virtual%> outside class declaration");
       virtualp = 0;
     }
 
@@ -7744,15 +7941,10 @@ grokdeclarator (const cp_declarator *declarator,
       error ("multiple storage classes in declaration of %qs", name);
       thread_p = false;
     }
-  if (declspecs->conflicting_specifiers_p)
-    {
-      error ("conflicting specifiers in declaration of %qs", name);
-      storage_class = sc_none;
-    }
-  else if (decl_context != NORMAL
-          && ((storage_class != sc_none
-               && storage_class != sc_mutable)
-              || thread_p))
+  if (decl_context != NORMAL
+      && ((storage_class != sc_none
+          && storage_class != sc_mutable)
+         || thread_p))
     {
       if ((decl_context == PARM || decl_context == CATCHPARM)
          && (storage_class == sc_register
@@ -7888,7 +8080,7 @@ grokdeclarator (const cp_declarator *declarator,
            if (type_quals != TYPE_UNQUALIFIED)
              {
                if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
-                 warning (OPT_Wreturn_type,
+                 warning (OPT_Wignored_qualifiers,
                           "type qualifiers ignored on function return type");
                /* We now know that the TYPE_QUALS don't apply to the
                   decl, but to its return type.  */
@@ -8050,7 +8242,8 @@ grokdeclarator (const cp_declarator *declarator,
          type_quals = TYPE_UNQUALIFIED;
 
          if (declarator->kind == cdk_ptrmem
-             && (TREE_CODE (type) == FUNCTION_TYPE || memfn_quals))
+             && (TREE_CODE (type) == FUNCTION_TYPE
+                 || (memfn_quals && TREE_CODE (type) == METHOD_TYPE)))
            {
              memfn_quals |= cp_type_quals (type);
              type = build_memfn_type (type,
@@ -8389,8 +8582,6 @@ grokdeclarator (const cp_declarator *declarator,
          && TYPE_NAME (type)
          && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
          && TYPE_ANONYMOUS_P (type)
-         /* Don't do this if there are attributes.  */
-         && (!attrlist || !*attrlist)
          && cp_type_quals (type) == TYPE_UNQUALIFIED)
        {
          tree oldname = TYPE_NAME (type);
@@ -8687,6 +8878,13 @@ grokdeclarator (const cp_declarator *declarator,
                    return error_mark_node;
                  }
              }
+           else if (sfk == sfk_constructor && friendp)
+             {
+               error ("expected qualified name in friend declaration "
+                      "for constructor %qD",
+                      id_declarator->u.id.unqualified_name);
+               return error_mark_node;
+             }
 
            /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node.  */
            function_context = (ctype != NULL_TREE) ?
@@ -9021,9 +9219,9 @@ grokdeclarator (const cp_declarator *declarator,
     else if (storage_class == sc_static)
       DECL_THIS_STATIC (decl) = 1;
 
-    /* Record constancy and volatility.  There's no need to do this
-       when processing a template; we'll do this for the instantiated
-       declaration based on the type of DECL.  */
+    /* Record constancy and volatility on the DECL itself .  There's
+       no need to do this when processing a template; we'll do this
+       for the instantiated declaration based on the type of DECL.  */
     if (!processing_template_decl)
       cp_apply_type_quals_to_decl (type_quals, decl);
 
@@ -9214,6 +9412,16 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms)
          TREE_TYPE (decl) = error_mark_node;
        }
 
+      if (type != error_mark_node
+         && TYPE_FOR_JAVA (type)
+         && MAYBE_CLASS_TYPE_P (type))
+       {
+         error ("parameter %qD has Java class type", decl);
+         type = error_mark_node;
+         TREE_TYPE (decl) = error_mark_node;
+         init = NULL_TREE;
+       }
+
       if (type != error_mark_node)
        {
          /* Top-level qualifiers on the parameters are
@@ -9405,7 +9613,8 @@ move_fn_p (const_tree d)
 
 /* Remember any special properties of member function DECL.  */
 
-void grok_special_member_properties (tree decl)
+void
+grok_special_member_properties (tree decl)
 {
   tree class_type;
 
@@ -9417,7 +9626,8 @@ void grok_special_member_properties (tree decl)
     {
       int ctor = copy_fn_p (decl);
 
-      TYPE_HAS_CONSTRUCTOR (class_type) = 1;
+      if (!DECL_ARTIFICIAL (decl))
+       TYPE_HAS_USER_CONSTRUCTOR (class_type) = 1;
 
       if (ctor > 0)
        {
@@ -9613,7 +9823,10 @@ grok_op_properties (tree decl, bool complain)
     }
 
   if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR)
-    TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
+    {
+      TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
+      DECL_IS_OPERATOR_NEW (decl) = 1;
+    }
   else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
     TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
   else
@@ -9649,10 +9862,11 @@ grok_op_properties (tree decl, bool complain)
                  if (arg == error_mark_node)
                    return false;
 
-                 /* IS_AGGR_TYPE, rather than CLASS_TYPE_P, is used
+                 /* MAYBE_CLASS_TYPE_P, rather than CLASS_TYPE_P, is used
                     because these checks are performed even on
                     template functions.  */
-                 if (IS_AGGR_TYPE (arg) || TREE_CODE (arg) == ENUMERAL_TYPE)
+                 if (MAYBE_CLASS_TYPE_P (arg)
+                     || TREE_CODE (arg) == ENUMERAL_TYPE)
                    break;
                }
 
@@ -9693,7 +9907,7 @@ grok_op_properties (tree decl, bool complain)
              if (t == class_type)
                what = "the same type";
              /* Don't force t to be complete here.  */
-             else if (IS_AGGR_TYPE (t)
+             else if (MAYBE_CLASS_TYPE_P (t)
                       && COMPLETE_TYPE_P (t)
                       && DERIVED_FROM_P (t, class_type))
                what = "a base class";
@@ -10167,14 +10381,14 @@ xref_tag (enum tag_types tag_code, tree name,
        }
       else
        {
-         t = make_aggr_type (code);
+         t = make_class_type (code);
          TYPE_CONTEXT (t) = context;
          t = pushtag (name, t, scope);
        }
     }
   else
     {
-      if (template_header_p && IS_AGGR_TYPE (t))
+      if (template_header_p && MAYBE_CLASS_TYPE_P (t))
         {
          if (!redeclare_class_template (t, current_template_parms))
             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
@@ -10637,7 +10851,8 @@ finish_enum (tree enumtype)
       saved_location = input_location;
       input_location = DECL_SOURCE_LOCATION (decl);
       value = perform_implicit_conversion (underlying_type,
-                                          DECL_INITIAL (decl));
+                                          DECL_INITIAL (decl),
+                                          tf_warning_or_error);
       input_location = saved_location;
 
       /* Do not clobber shared ints.  */
@@ -10770,7 +10985,6 @@ build_enumerator (tree name, tree value, tree enumtype)
 
   DECL_CONTEXT (decl) = FROB_CONTEXT (context);
   TREE_CONSTANT (decl) = 1;
-  TREE_INVARIANT (decl) = 1;
   TREE_READONLY (decl) = 1;
   DECL_INITIAL (decl) = value;
 
@@ -10800,11 +11014,15 @@ check_function_type (tree decl, tree current_function_parms)
 
   if (dependent_type_p (return_type))
     return;
-  if (!COMPLETE_OR_VOID_TYPE_P (return_type))
+  if (!COMPLETE_OR_VOID_TYPE_P (return_type)
+      || (TYPE_FOR_JAVA (return_type) && MAYBE_CLASS_TYPE_P (return_type)))
     {
       tree args = TYPE_ARG_TYPES (fntype);
 
-      error ("return type %q#T is incomplete", return_type);
+      if (!COMPLETE_OR_VOID_TYPE_P (return_type))
+       error ("return type %q#T is incomplete", return_type);
+      else
+       error ("return type has Java class type %q#T", return_type);
 
       /* Make it return void instead.  */
       if (TREE_CODE (fntype) == METHOD_TYPE)
@@ -11066,14 +11284,19 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
      CFUN set up, and our per-function variables initialized.
      FIXME factor out the non-RTL stuff.  */
   bl = current_binding_level;
-  allocate_struct_function (decl1);
+  allocate_struct_function (decl1, processing_template_decl);
+
+  /* Initialize the language data structures.  Whenever we start
+     a new function, we destroy temporaries in the usual way.  */
+  cfun->language = GGC_CNEW (struct language_function);
+  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
   current_binding_level = bl;
 
   /* Even though we're inside a function body, we still don't want to
      call expand_expr to calculate the size of a variable-sized array.
      We haven't necessarily assigned RTL to all variables yet, so it's
      not safe to try to expand expressions involving them.  */
-  cfun->x_dont_save_pending_sizes_p = 1;
+  cfun->dont_save_pending_sizes_p = 1;
 
   /* Start the statement-tree, start the tree now.  */
   DECL_SAVED_TREE (decl1) = push_stmt_list ();
@@ -11095,7 +11318,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       gcc_assert (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE);
 
       cp_function_chain->x_current_class_ref
-       = build_indirect_ref (t, NULL);
+       = cp_build_indirect_ref (t, NULL, tf_warning_or_error);
       cp_function_chain->x_current_class_ptr = t;
 
       /* Constructors and destructors need to know whether they're "in
@@ -11536,7 +11759,7 @@ finish_function_body (tree compstmt)
    of curly braces, skipping the artificial block created for constructor
    initializers.  */
 
-static tree
+tree
 outer_curly_brace_block (tree fndecl)
 {
   tree block = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl));
@@ -11609,11 +11832,10 @@ finish_function (int flags)
          /* Hack.  We don't want the middle-end to warn that this
             return is unreachable, so put the statement on the
             special line 0.  */
-#ifdef USE_MAPPED_LOCATION
-         SET_EXPR_LOCATION (stmt, UNKNOWN_LOCATION);
-#else
-         annotate_with_file_line (stmt, input_filename, 0);
-#endif
+         {
+           location_t linezero = linemap_line_start (line_table, 0, 1);
+           SET_EXPR_LOCATION (stmt, linezero);
+         }
        }
 
       if (use_eh_spec_block (current_function_decl))
@@ -12013,8 +12235,9 @@ cxx_maybe_build_cleanup (tree decl)
       fn = lookup_name (id);
       arg = build_address (decl);
       mark_used (decl);
-      cleanup = build_function_call (fn, build_tree_list (NULL_TREE,
-                                                         arg));
+      cleanup = cp_build_function_call (fn, build_tree_list (NULL_TREE,
+                                                            arg),
+                                       tf_warning_or_error);
     }
   /* Handle ordinary C++ destructors.  */
   type = TREE_TYPE (decl);
@@ -12029,10 +12252,7 @@ cxx_maybe_build_cleanup (tree decl)
       if (TREE_CODE (type) == ARRAY_TYPE)
        addr = decl;
       else
-       {
-         cxx_mark_addressable (decl);
-         addr = build_unary_op (ADDR_EXPR, decl, 0);
-       }
+       addr = build_address (decl);
 
       /* Optimize for space over speed here.  */
       if (!has_vbases || flag_expensive_optimizations)
@@ -12081,47 +12301,6 @@ revert_static_member_fn (tree decl)
   DECL_STATIC_FUNCTION_P (decl) = 1;
 }
 
-/* Initialize the variables used during compilation of a C++
-   function.  */
-
-void
-cxx_push_function_context (struct function * f)
-{
-  struct language_function *p = GGC_CNEW (struct language_function);
-  f->language = p;
-
-  /* Whenever we start a new function, we destroy temporaries in the
-     usual way.  */
-  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
-
-  if (f->decl)
-    {
-      tree fn = f->decl;
-
-      if (DECL_SAVED_FUNCTION_DATA (fn))
-       {
-         /* If we already parsed this function, and we're just expanding it
-            now, restore saved state.  */
-         *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);
-
-         /* We don't need the saved data anymore.  Unless this is an inline
-            function; we need the named return value info for
-            declare_return_variable.  */
-         if (! DECL_INLINE (fn))
-           DECL_SAVED_FUNCTION_DATA (fn) = NULL;
-       }
-    }
-}
-
-/* Free the language-specific parts of F, now that we've finished
-   compiling the function.  */
-
-void
-cxx_pop_function_context (struct function * f)
-{
-  f->language = 0;
-}
-
 /* Return which tree structure is used by T, or TS_CP_GENERIC if T is
    one of the language-independent trees.  */