OSDN Git Service

Implement C++11 user-defined literals.
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index e30fe18..5ba5008 100644 (file)
@@ -71,7 +71,7 @@ static void require_complete_types_for_parms (tree);
 static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
-static tree grok_reference_init (tree, tree, tree, tree *);
+static tree grok_reference_init (tree, tree, tree, tree *, int);
 static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
                         int, int, tree);
 static int check_static_variable_definition (tree, tree);
@@ -1203,6 +1203,21 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       || TREE_TYPE (olddecl) == error_mark_node)
     return error_mark_node;
 
+  if (UDLIT_OPER_P (DECL_NAME (newdecl))
+      && UDLIT_OPER_P (DECL_NAME (olddecl)))
+    {
+      if (TREE_CODE (newdecl) == TEMPLATE_DECL
+         && TREE_CODE (olddecl) != TEMPLATE_DECL
+         && check_raw_literal_operator (olddecl))
+       error ("literal operator template %q+D conflicts with"
+              " raw literal operator %qD", newdecl, olddecl);
+      else if (TREE_CODE (newdecl) != TEMPLATE_DECL
+              && TREE_CODE (olddecl) == TEMPLATE_DECL
+              && check_raw_literal_operator (newdecl))
+       error ("raw literal operator %q+D conflicts with"
+              " literal operator template %qD", newdecl, olddecl);
+    }
+
   if (DECL_P (olddecl)
       && TREE_CODE (newdecl) == FUNCTION_DECL
       && TREE_CODE (olddecl) == FUNCTION_DECL
@@ -1357,11 +1372,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       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;
+         && !TREE_NOTHROW (olddecl))
+       {
+         enum built_in_function fncode = DECL_FUNCTION_CODE (olddecl);
+         tree tmpdecl = builtin_decl_explicit (fncode);
+         if (tmpdecl && tmpdecl != olddecl && types_match)
+           TREE_NOTHROW (tmpdecl)  = 1;
+       }
 
       /* Whether or not the builtin can throw exceptions has no
         bearing on this declarator.  */
@@ -1540,8 +1557,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          error_at (DECL_SOURCE_LOCATION (newdecl), errmsg, newdecl);
          if (DECL_NAME (olddecl) != NULL_TREE)
            error ((DECL_INITIAL (olddecl) && namespace_bindings_p ())
-                        ? "%q+#D previously defined here"
-                        : "%q+#D previously declared here", olddecl);
+                  ? G_("%q+#D previously defined here")
+                  : G_("%q+#D previously declared here"), olddecl);
          return error_mark_node;
        }
       else if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -2135,6 +2152,22 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
              /* If we're keeping the built-in definition, keep the rtl,
                 regardless of declaration matches.  */
              COPY_DECL_RTL (olddecl, newdecl);
+             if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
+               {
+                 enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
+                 switch (fncode)
+                   {
+                     /* If a compatible prototype of these builtin functions
+                        is seen, assume the runtime implements it with the
+                        expected semantics.  */
+                   case BUILT_IN_STPCPY:
+                     if (builtin_decl_explicit_p (fncode))
+                       set_builtin_decl_implicit_p (fncode, true);
+                     break;
+                   default:
+                     break;
+                   }
+               }
            }
 
          DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
@@ -2665,7 +2698,8 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
       tree new_decls, old_decls = (b == level ? names : NULL_TREE);
 
       for (new_decls = b->names; new_decls != old_decls;
-          new_decls = DECL_CHAIN (new_decls))
+          new_decls = (DECL_P (new_decls) ? DECL_CHAIN (new_decls)
+                       : TREE_CHAIN (new_decls)))
        {
          int problem = decl_jump_unsafe (new_decls);
          if (! problem)
@@ -3217,8 +3251,8 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   if (!t)
     {
       if (complain & tf_error)
-       error (want_template ? "no class template named %q#T in %q#T"
-              : "no type named %q#T in %q#T", name, context);
+       error (want_template ? G_("no class template named %q#T in %q#T")
+              : G_("no type named %q#T in %q#T"), name, context);
       return error_mark_node;
     }
   
@@ -3636,7 +3670,7 @@ cxx_init_decl_processing (void)
   current_lang_name = lang_name_cplusplus;
 
   {
-    tree newattrs;
+    tree newattrs, extvisattr;
     tree newtype, deltype;
     tree ptr_ftype_sizetype;
     tree new_eh_spec;
@@ -3666,12 +3700,15 @@ cxx_init_decl_processing (void)
 
     /* Ensure attribs.c is initialized.  */
     init_attributes ();
-    newattrs
-      = build_tree_list (get_identifier ("alloc_size"),
-                        build_tree_list (NULL_TREE, integer_one_node));
+    extvisattr = build_tree_list (get_identifier ("externally_visible"),
+                                 NULL_TREE);
+    newattrs = tree_cons (get_identifier ("alloc_size"),
+                         build_tree_list (NULL_TREE, integer_one_node),
+                         extvisattr);
     newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs);
     newtype = build_exception_variant (newtype, new_eh_spec);
-    deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
+    deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
+    deltype = build_exception_variant (deltype, empty_except_spec);
     push_cp_library_fn (NEW_EXPR, newtype);
     push_cp_library_fn (VEC_NEW_EXPR, newtype);
     global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
@@ -4574,7 +4611,8 @@ start_decl_1 (tree decl, bool initialized)
    Quotes on semantics can be found in ARM 8.4.3.  */
 
 static tree
-grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
+grok_reference_init (tree decl, tree type, tree init, tree *cleanup,
+                    int flags)
 {
   tree tmp;
 
@@ -4603,7 +4641,8 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
      DECL_INITIAL for local references (instead assigning to them
      explicitly); we need to allow the temporary to be initialized
      first.  */
-  tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error);
+  tmp = initialize_reference (type, init, decl, cleanup, flags,
+                             tf_warning_or_error);
   if (DECL_DECLARED_CONSTEXPR_P (decl))
     {
       tmp = cxx_constant_value (tmp);
@@ -4897,15 +4936,16 @@ check_for_uninitialized_const_var (tree decl)
   if (TREE_CODE (decl) == VAR_DECL
       && TREE_CODE (type) != REFERENCE_TYPE
       && CP_TYPE_CONST_P (type)
-      && (!TYPE_NEEDS_CONSTRUCTING (type)
-         || !type_has_user_provided_default_constructor (type))
       && !DECL_INITIAL (decl))
     {
+      tree field = default_init_uninitialized_part (type);
+      if (!field)
+       return;
+
       permerror (DECL_SOURCE_LOCATION (decl),
                 "uninitialized const %qD", decl);
 
-      if (CLASS_TYPE_P (type)
-         && !type_has_user_provided_default_constructor (type))
+      if (CLASS_TYPE_P (type))
        {
          tree defaulted_ctor;
 
@@ -4916,6 +4956,8 @@ check_for_uninitialized_const_var (tree decl)
            inform (DECL_SOURCE_LOCATION (defaulted_ctor),
                    "constructor is not user-provided because it is "
                    "explicitly defaulted in the class body");
+         inform (0, "and the implicitly-defined constructor does not "
+                 "initialize %q+#D", field);
        }
     }
 }
@@ -5468,7 +5510,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
   else if (!init && DECL_REALLY_EXTERN (decl))
     ;
   else if (TREE_CODE (type) == REFERENCE_TYPE)
-    init = grok_reference_init (decl, type, init, cleanup);
+    init = grok_reference_init (decl, type, init, cleanup, flags);
   else if (init || type_build_ctor_call (type))
     {
       if (!init)
@@ -5691,7 +5733,9 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
 static tree
 wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data)
 {
-  if (TYPE_P (*stmt_p))
+  /* Stop at types or full-expression boundaries.  */
+  if (TYPE_P (*stmt_p)
+      || TREE_CODE (*stmt_p) == CLEANUP_POINT_EXPR)
     {
       *walk_subtrees = 0;
       return NULL_TREE;
@@ -6070,6 +6114,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       return;
     }
 
+  /* Just store non-static data member initializers for later.  */
+  if (init && TREE_CODE (decl) == FIELD_DECL)
+    DECL_INITIAL (decl) = init;
+
   /* Take care of TYPE_DECLs up front.  */
   if (TREE_CODE (decl) == TYPE_DECL)
     {
@@ -7312,6 +7360,47 @@ grokfndecl (tree ctype,
   if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))
       && !grok_op_properties (decl, /*complain=*/true))
     return NULL_TREE;
+  else if (UDLIT_OPER_P (DECL_NAME (decl)))
+    {
+      bool long_long_unsigned_p;
+      bool long_double_p;
+      const char *suffix = NULL;
+      /* [over.literal]/6: Literal operators shall not have C linkage. */
+      if (DECL_LANGUAGE (decl) == lang_c)
+       {
+         error ("literal operator with C linkage");
+         return NULL_TREE;
+       }
+
+      if (DECL_NAMESPACE_SCOPE_P (decl))
+       {
+         if (!check_literal_operator_args (decl, &long_long_unsigned_p,
+                                           &long_double_p))
+           {
+             error ("%qD has invalid argument list", decl);
+             return NULL_TREE;
+           }
+
+         suffix = UDLIT_OP_SUFFIX (DECL_NAME (decl));
+         if (long_long_unsigned_p)
+           {
+             if (cpp_interpret_int_suffix (suffix, strlen (suffix)))
+               warning (0, "integer suffix %<%s%>"
+                           " shadowed by implementation", suffix);
+           }
+         else if (long_double_p)
+           {
+             if (cpp_interpret_float_suffix (suffix, strlen (suffix)))
+               warning (0, "floating point suffix %<%s%>"
+                           " shadowed by implementation", suffix);
+           }
+       }
+      else
+       {
+         error ("%qD must be a non-member function", decl);
+         return NULL_TREE;
+       }
+    }
 
   if (funcdef_flag)
     /* Make the init_value nonzero so pushdecl knows this is not
@@ -7397,6 +7486,12 @@ grokfndecl (tree ctype,
              error ("definition of implicitly-declared %qD", old_decl);
              return NULL_TREE;
            }
+         else if (DECL_DEFAULTED_FN (old_decl))
+           {
+             error ("definition of explicitly-defaulted %q+D", decl);
+             error ("%q+#D explicitly defaulted here", old_decl);
+             return NULL_TREE;
+           }
 
          /* Since we've smashed OLD_DECL to its
             DECL_TEMPLATE_RESULT, we must do the same to DECL.  */
@@ -7714,8 +7809,9 @@ check_static_variable_definition (tree decl, tree type)
   else if (cxx_dialect >= cxx0x && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     {
       if (literal_type_p (type))
-       error ("%<constexpr%> needed for in-class initialization of static "
-              "data member %q#D of non-integral type", decl);
+       permerror (input_location,
+                  "%<constexpr%> needed for in-class initialization of "
+                  "static data member %q#D of non-integral type", decl);
       else
        error ("in-class initialization of static data member %q#D of "
               "non-literal type", decl);
@@ -8496,6 +8592,15 @@ grokdeclarator (const cp_declarator *declarator,
       error ("declaration of %qD as non-function", dname);
       return error_mark_node;
     }
+  if (dname
+      && TREE_CODE (dname) == IDENTIFIER_NODE
+      && UDLIT_OPER_P (dname)
+      && innermost_code != cdk_function)
+    {
+      error ("declaration of %qD as non-function", dname);
+      return error_mark_node;
+    }
 
   if (dname && IDENTIFIER_OPNAME_P (dname))
     {
@@ -8638,6 +8743,18 @@ grokdeclarator (const cp_declarator *declarator,
 
   ctype = NULL_TREE;
 
+  if (explicit_int128)
+    {
+      if (int128_integer_type_node == NULL_TREE)
+       {
+         error ("%<__int128%> is not supported by this target");
+         explicit_int128 = false;
+       }
+      else if (pedantic && ! in_system_header)
+       pedwarn (input_location, OPT_pedantic,
+                "ISO C++ does not support %<__int128%> for %qs", name);
+    }
+
   /* Now process the modifiers that were specified
      and check for invalid combinations.  */
 
@@ -8661,8 +8778,6 @@ grokdeclarator (const cp_declarator *declarator,
        error ("%<signed%> and %<unsigned%> specified together for %qs", name);
       else if (longlong && TREE_CODE (type) != INTEGER_TYPE)
        error ("%<long long%> invalid for %qs", name);
-      else if (explicit_int128 && TREE_CODE (type) != INTEGER_TYPE)
-       error ("%<__int128%> invalid for %qs", name);
       else if (long_p && TREE_CODE (type) == REAL_TYPE)
        error ("%<long%> invalid for %qs", name);
       else if (short_p && TREE_CODE (type) == REAL_TYPE)
@@ -8693,22 +8808,6 @@ grokdeclarator (const cp_declarator *declarator,
              if (flag_pedantic_errors)
                ok = 0;
            }
-         if (explicit_int128)
-           {
-             if (int128_integer_type_node == NULL_TREE)
-               {
-                 error ("%<__int128%> is not supported by this target");
-                 ok = 0;
-               }
-             else if (pedantic)
-               {
-                 pedwarn (input_location, OPT_pedantic,
-                          "ISO C++ does not support %<__int128%> for %qs",
-                          name);
-                 if (flag_pedantic_errors)
-                   ok = 0;
-               }
-           }
        }
 
       /* Discard the type modifiers if they are invalid.  */
@@ -8719,7 +8818,6 @@ grokdeclarator (const cp_declarator *declarator,
          long_p = false;
          short_p = false;
          longlong = 0;
-         explicit_int128 = false;
        }
     }
 
@@ -9112,13 +9210,13 @@ grokdeclarator (const cp_declarator *declarator,
                   virtual.  A constructor may not be static.  */
                if (staticp == 2)
                  error ((flags == DTOR_FLAG)
-                        ? "destructor cannot be static member function"
-                        : "constructor cannot be static member function");
+                        ? G_("destructor cannot be static member function")
+                        : G_("constructor cannot be static member function"));
                if (memfn_quals)
                  {
                    error ((flags == DTOR_FLAG)
-                          ? "destructors may not be cv-qualified"
-                          : "constructors may not be cv-qualified");
+                          ? G_("destructors may not be cv-qualified")
+                          : G_("constructors may not be cv-qualified"));
                    memfn_quals = TYPE_UNQUALIFIED;
                  }
 
@@ -9471,8 +9569,10 @@ grokdeclarator (const cp_declarator *declarator,
              && (!friendp || funcdef_flag))
            {
              error (funcdef_flag
-                    ? "cannot define member function %<%T::%s%> within %<%T%>"
-                    : "cannot declare member function %<%T::%s%> within %<%T%>",
+                    ? G_("cannot define member function %<%T::%s%> "
+                         "within %<%T%>")
+                    : G_("cannot declare member function %<%T::%s%> "
+                         "within %<%T%>"),
                     ctype, name, current_class_type);
              return error_mark_node;
            }
@@ -10088,36 +10188,6 @@ grokdeclarator (const cp_declarator *declarator,
 
        if (decl == NULL_TREE)
          {
-           if (initialized)
-             {
-               if (!staticp)
-                 {
-                   /* An attempt is being made to initialize a non-static
-                      member.  But, from [class.mem]:
-
-                      4 A member-declarator can contain a
-                      constant-initializer only if it declares a static
-                      member (_class.static_) of integral or enumeration
-                      type, see _class.static.data_.
-
-                      This used to be relatively common practice, but
-                      the rest of the compiler does not correctly
-                      handle the initialization unless the member is
-                      static so we make it static below.  */
-                   if (cxx_dialect >= cxx0x)
-                     {
-                       sorry ("non-static data member initializers");
-                     }
-                   else
-                     {
-                       permerror (input_location, "ISO C++ forbids initialization of member %qD",
-                                  unqualified_id);
-                       permerror (input_location, "making %qD static", unqualified_id);
-                       staticp = 1;
-                     }
-                 }
-             }
-
            if (staticp)
              {
                /* C++ allows static class members.  All other work
@@ -10158,6 +10228,11 @@ grokdeclarator (const cp_declarator *declarator,
                    DECL_MUTABLE_P (decl) = 1;
                    storage_class = sc_none;
                  }
+
+               if (initialized)
+                 /* An attempt is being made to initialize a non-static
+                    member.  This is new in C++11.  */
+                 maybe_warn_cpp0x (CPP0X_NSDMI);
              }
 
            bad_specifiers (decl, BSP_FIELD, virtualp,
@@ -10217,8 +10292,8 @@ grokdeclarator (const cp_declarator *declarator,
                     || sfk == sfk_destructor)
              {
                error (funcdef_flag
-                      ? "%qs defined in a non-class scope"
-                      : "%qs declared in a non-class scope", name);
+                      ? G_("%qs defined in a non-class scope")
+                      : G_("%qs declared in a non-class scope"), name);
                sfk = sfk_none;
              }
          }
@@ -11597,9 +11672,10 @@ xref_tag (enum tag_types tag_code, tree name,
           tag_scope scope, bool template_header_p)
 {
   tree ret;
-  timevar_start (TV_NAME_LOOKUP);
+  bool subtime;
+  subtime = timevar_cond_start (TV_NAME_LOOKUP);
   ret = xref_tag_1 (tag_code, name, scope, template_header_p);
-  timevar_stop (TV_NAME_LOOKUP);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return ret;
 }
 
@@ -13392,6 +13468,10 @@ finish_function (int flags)
       unused_but_set_errorcount = errorcount;
     }
 
+  /* Complain about locally defined typedefs that are not used in this
+     function.  */
+  maybe_warn_unused_local_typedefs ();
+
   /* Genericize before inlining.  */
   if (!processing_template_decl)
     {
@@ -13739,6 +13819,7 @@ cp_tree_node_structure (union lang_tree_node * t)
     case TRAIT_EXPR:           return TS_CP_TRAIT_EXPR;
     case LAMBDA_EXPR:          return TS_CP_LAMBDA_EXPR;
     case TEMPLATE_INFO:                return TS_CP_TEMPLATE_INFO;
+    case USERDEF_LITERAL:      return TS_CP_USERDEF_LITERAL;
     default:                   return TS_CP_GENERIC;
     }
 }