Hi,

as I mentioned a few days ago, since this function grew rather big, I hope to clean it up a bit. For now at least nothing ground shaking: I moved together some declarations and initializations; in other cases exploited the opportunity C++ gives to defer declarations; consistently changed some int flags to bool (and avoiding names ending by *p for non bools); plus rather obvious stylistic tweaks (like wrapping way overlong lines). I'm also improving a bit the diagnostics - see the new testcases - telling apart <inline> and <constexpr> in two error messages. It's a start. How does it look to you?

Tested x86_64-linux.

Thanks,
Paolo.

/////////////////////////////
/cp
2013-03-20  Paolo Carlini  <paolo.carl...@oracle.com>

        * decl.c (grokdeclarator): Tidy.
        (bad_specifiers): Likewise.
        (grokfndecl): Likewise; improve error messages.

/testsuite
2013-03-20  Paolo Carlini  <paolo.carl...@oracle.com>

        * g++.dg/cpp0x/constexpr-friend-2.C: New.
        * g++.dg/cpp0x/constexpr-main.C: Likewise.
Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 196797)
+++ cp/decl.c   (working copy)
@@ -77,8 +77,8 @@ static void record_unknown_type (tree, const char
 static tree builtin_function_1 (tree, tree, bool);
 static tree build_library_fn_1 (tree, enum tree_code, tree);
 static int member_function_or_else (tree, tree, enum overload_flags);
-static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
-                           int);
+static void bad_specifiers (tree, enum bad_spec_place, bool, bool, bool,
+                           bool, bool);
 static void check_for_uninitialized_const_var (tree);
 static hashval_t typename_hash (const void *);
 static int typename_compare (const void *, const void *);
@@ -7154,11 +7154,11 @@ member_function_or_else (tree ctype, tree cur_type
 static void
 bad_specifiers (tree object,
                enum bad_spec_place type,
-               int virtualp,
-               int quals,
-               int inlinep,
-               int friendp,
-               int raises)
+               bool virtualp,
+               bool quals,
+               bool inlinep,
+               bool friendp,
+               bool raises)
 {
   switch (type)
     {
@@ -7310,14 +7310,15 @@ grokfndecl (tree ctype,
            tree declarator,
            tree parms,
            tree orig_declarator,
-           int virtualp,
+           bool virtualp,
            enum overload_flags flags,
            cp_cv_quals quals,
            tree raises,
            int check,
-           int friendp,
-           int publicp,
-           int inlinep,
+           bool friendp,
+           bool publicp,
+           bool inlinep,
+           bool constexprp,
            special_function_kind sfk,
            bool funcdef_flag,
            int template_count,
@@ -7326,7 +7327,7 @@ grokfndecl (tree ctype,
            location_t location)
 {
   tree decl;
-  int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
+  bool staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
   tree t;
 
   if (raises)
@@ -7427,13 +7428,14 @@ grokfndecl (tree ctype,
              return NULL_TREE;
            }
 
-         if (inlinep)
-           {
-             error ("%<inline%> is not allowed in declaration of friend "
-                    "template specialization %qD",
-                    decl);
-             return NULL_TREE;
-           }
+         if (inlinep)
+           error ("%<inline%> is not allowed in declaration of friend "
+                  "template specialization %qD", decl);
+         if (constexprp)
+           error ("%<constexpr%> is not allowed in declaration of friend "
+                  "template specialization %qD", decl);
+         if (inlinep || constexprp)
+           return NULL_TREE;
        }
     }
 
@@ -7474,17 +7476,20 @@ grokfndecl (tree ctype,
        error ("cannot declare %<::main%> to be a template");
       if (inlinep)
        error ("cannot declare %<::main%> to be inline");
+      if (constexprp)
+       error ("cannot declare %<::main%> to be constexpr");
       if (!publicp)
        error ("cannot declare %<::main%> to be static");
-      inlinep = 0;
-      publicp = 1;
+      inlinep = false;
+      constexprp = false;
+      publicp = true;
     }
 
   /* Members of anonymous types and local classes have no linkage; make
      them internal.  If a typedef is made later, this will be changed.  */
   if (ctype && (TYPE_ANONYMOUS_P (ctype)
                || decl_function_context (TYPE_MAIN_DECL (ctype))))
-    publicp = 0;
+    publicp = false;
 
   if (publicp && cxx_dialect == cxx98)
     {
@@ -7526,9 +7531,9 @@ grokfndecl (tree ctype,
     }
 
   /* If the declaration was declared inline, mark it as such.  */
-  if (inlinep)
+  if (inlinep || constexprp)
     DECL_DECLARED_INLINE_P (decl) = 1;
-  if (inlinep & 2)
+  if (constexprp)
     DECL_DECLARED_CONSTEXPR_P (decl) = true;
 
   DECL_EXTERNAL (decl) = 1;
@@ -7611,7 +7616,7 @@ grokfndecl (tree ctype,
   decl = check_explicit_specialization (orig_declarator, decl,
                                        template_count,
                                        2 * funcdef_flag +
-                                       4 * (friendp != 0));
+                                       4 * friendp);
   if (decl == error_mark_node)
     return NULL_TREE;
 
@@ -8591,21 +8596,13 @@ grokdeclarator (const cp_declarator *declarator,
                int initialized,
                tree* attrlist)
 {
-  tree type = NULL_TREE;
-  int longlong = 0;
-  int explicit_int128 = 0;
-  int virtualp, explicitp, friendp, inlinep, staticp;
-  int explicit_int = 0;
-  int explicit_char = 0;
-  int defaulted_int = 0;
-
   tree typedef_decl = NULL_TREE;
   const char *name = NULL;
   tree typedef_type = NULL_TREE;
   /* True if this declarator is a function definition.  */
   bool funcdef_flag = false;
   cp_declarator_kind innermost_code = cdk_error;
-  int bitfield = 0;
+  bool bitfield_p = false;
 #if 0
   /* See the code below that used this.  */
   tree decl_attr = NULL_TREE;
@@ -8625,8 +8622,6 @@ grokdeclarator (const cp_declarator *declarator,
   /* virt-specifiers that apply to the declarator, for a declaration of
      a member function.  */
   cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
-  /* cv-qualifiers that apply to the type specified by the DECLSPECS.  */
-  int type_quals;
   tree raises = NULL_TREE;
   int template_count = 0;
   tree returned_attrs = NULL_TREE;
@@ -8645,30 +8640,30 @@ grokdeclarator (const cp_declarator *declarator,
      this value will be NULL_TREE, even if the entity is located at
      namespace scope.  */
   tree in_namespace = NULL_TREE;
-  cp_storage_class storage_class;
-  bool unsigned_p, signed_p, short_p, long_p, thread_p;
+  bool unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned);
+  bool signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
+  bool short_p = decl_spec_seq_has_spec_p (declspecs, ds_short);
+  bool long_p = decl_spec_seq_has_spec_p (declspecs, ds_long);
+  bool longlong_p = decl_spec_seq_has_spec_p (declspecs, ds_long_long);
+  bool thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread);
+  bool typedef_p = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
+  bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
+  bool explicit_int = declspecs->explicit_int_p;
+  bool explicit_char = declspecs->explicit_char_p;
+  bool explicit_int128 = declspecs->explicit_int128_p;
+  bool defaulted_int = false;
   bool type_was_error_mark_node = false;
-  bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
+  bool parameter_pack_p = declarator ? declarator->parameter_pack_p : false;
   bool template_type_arg = false;
   bool template_parm_flag = false;
-  bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
   source_location saved_loc = input_location;
-  const char *errmsg;
 
-  signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
-  unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned);
-  short_p = decl_spec_seq_has_spec_p (declspecs, ds_short);
-  long_p = decl_spec_seq_has_spec_p (declspecs, ds_long);
-  longlong = decl_spec_seq_has_spec_p (declspecs, ds_long_long);
-  explicit_int128 = declspecs->explicit_int128_p;
-  thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread);
-
   if (decl_context == FUNCDEF)
     funcdef_flag = true, decl_context = NORMAL;
   else if (decl_context == MEMFUNCDEF)
     funcdef_flag = true, decl_context = FIELD;
   else if (decl_context == BITFIELD)
-    bitfield = 1, decl_context = FIELD;
+    bitfield_p = true, decl_context = FIELD;
   else if (decl_context == TEMPLATE_TYPE_ARG)
     template_type_arg = true, decl_context = TYPENAME;
   else if (decl_context == TPARM)
@@ -8751,8 +8746,6 @@ grokdeclarator (const cp_declarator *declarator,
              {
              case BIT_NOT_EXPR:
                {
-                 tree type;
-
                  if (innermost_code != cdk_function)
                    {
                      error ("declaration of %qD as non-function", decl);
@@ -8765,7 +8758,7 @@ grokdeclarator (const cp_declarator *declarator,
                      return error_mark_node;
                    }
 
-                 type = TREE_OPERAND (decl, 0);
+                 tree type = TREE_OPERAND (decl, 0);
                  if (TYPE_P (type))
                    type = constructor_name (type);
                  name = identifier_to_locale (IDENTIFIER_POINTER (type));
@@ -8862,7 +8855,7 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (dname && IDENTIFIER_OPNAME_P (dname))
     {
-      if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+      if (typedef_p)
        {
          error ("declaration of %qD as %<typedef%>", dname);
          return error_mark_node;
@@ -8874,6 +8867,12 @@ grokdeclarator (const cp_declarator *declarator,
        }
     }
 
+  if (constexpr_p && typedef_p)
+    {
+      error ("%<constexpr%> cannot appear in a typedef declaration");
+      return error_mark_node;
+    }
+
   /* Anything declared one level down from the top level
      must be one of the parameters of a function
      (because the body is at least two levels down).  */
@@ -8900,12 +8899,6 @@ grokdeclarator (const cp_declarator *declarator,
   if (name == NULL)
     name = decl_context == PARM ? "parameter" : "type name";
 
-  if (constexpr_p && decl_spec_seq_has_spec_p (declspecs, ds_typedef))
-    {
-      error ("%<constexpr%> cannot appear in a typedef declaration");
-      return error_mark_node;
-    }
-
   /* If there were multiple types specified in the decl-specifier-seq,
      issue an error message.  */
   if (declspecs->multiple_types_p)
@@ -8921,7 +8914,7 @@ grokdeclarator (const cp_declarator *declarator,
     }
 
   /* Extract the basic type from the decl-specifier-seq.  */
-  type = declspecs->type;
+  tree type = declspecs->type;
   if (type == error_mark_node)
     {
       type = NULL_TREE;
@@ -8947,11 +8940,8 @@ grokdeclarator (const cp_declarator *declarator,
     {
       /* These imply 'int'.  */
       type = integer_type_node;
-      defaulted_int = 1;
+      defaulted_int = true;
     }
-  /* Gather flags.  */
-  explicit_int = declspecs->explicit_int_p;
-  explicit_char = declspecs->explicit_char_p;
 
 #if 0
   /* See the code below that used this.  */
@@ -8969,26 +8959,25 @@ grokdeclarator (const cp_declarator *declarator,
                                               ctor_return_type);
   else if (type == NULL_TREE)
     {
-      int is_main;
-
-      explicit_int = -1;
-
       /* We handle `main' specially here, because 'main () { }' is so
         common.  With no options, it is allowed.  With -Wreturn-type,
         it is a warning.  It is only an error with -pedantic-errors.  */
-      is_main = (funcdef_flag
-                && dname && TREE_CODE (dname) == IDENTIFIER_NODE
-                && MAIN_NAME_P (dname)
-                && ctype == NULL_TREE
-                && in_namespace == NULL_TREE
-                && current_namespace == global_namespace);
+      bool is_main = (funcdef_flag
+                     && dname && TREE_CODE (dname) == IDENTIFIER_NODE
+                     && MAIN_NAME_P (dname)
+                     && ctype == NULL_TREE
+                     && in_namespace == NULL_TREE
+                     && current_namespace == global_namespace);
 
+      explicit_int = true;
+
       if (type_was_error_mark_node)
        /* We've already issued an error, don't complain more.  */;
       else if (in_system_header || flag_ms_extensions)
        /* Allow it, sigh.  */;
       else if (! is_main)
-       permerror (input_location, "ISO C++ forbids declaration of %qs with no 
type", name);
+       permerror (input_location,
+                  "ISO C++ forbids declaration of %qs with no type", name);
       else if (pedantic)
        pedwarn (input_location, OPT_Wpedantic,
                 "ISO C++ forbids declaration of %qs with no type", name);
@@ -9017,7 +9006,7 @@ grokdeclarator (const cp_declarator *declarator,
      and check for invalid combinations.  */
 
   /* Long double is a special combination.  */
-  if (long_p && !longlong && TYPE_MAIN_VARIANT (type) == double_type_node)
+  if (long_p && !longlong_p && TYPE_MAIN_VARIANT (type) == double_type_node)
     {
       long_p = false;
       type = cp_build_qualified_type (long_double_type_node,
@@ -9028,13 +9017,13 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (unsigned_p || signed_p || long_p || short_p)
     {
-      int ok = 0;
+      bool ok = false;
 
       if ((signed_p || unsigned_p) && TREE_CODE (type) != INTEGER_TYPE)
        error ("%<signed%> or %<unsigned%> invalid for %qs", name);
       else if (signed_p && unsigned_p)
        error ("%<signed%> and %<unsigned%> specified together for %qs", name);
-      else if (longlong && TREE_CODE (type) != INTEGER_TYPE)
+      else if (longlong_p && TREE_CODE (type) != INTEGER_TYPE)
        error ("%<long long%> invalid for %qs", name);
       else if (long_p && TREE_CODE (type) == REAL_TYPE)
        error ("%<long%> invalid for %qs", name);
@@ -9042,8 +9031,10 @@ grokdeclarator (const cp_declarator *declarator,
        error ("%<short%> invalid for %qs", name);
       else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE)
        error ("%<long%> or %<short%> invalid for %qs", name);
-      else if ((long_p || short_p || explicit_char || explicit_int) && 
explicit_int128)
-       error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs", 
name);
+      else if ((long_p || short_p || explicit_char || explicit_int)
+              && explicit_int128)
+       error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs",
+              name);
       else if ((long_p || short_p) && explicit_char)
        error ("%<long%> or %<short%> specified with char for %qs", name);
       else if (long_p && short_p)
@@ -9057,14 +9048,15 @@ grokdeclarator (const cp_declarator *declarator,
        }
       else
        {
-         ok = 1;
-         if (!explicit_int && !defaulted_int && !explicit_char && 
!explicit_int128 && pedantic)
+         ok = true;
+         if (!explicit_int && !defaulted_int && !explicit_char
+             && !explicit_int128 && pedantic)
            {
              pedwarn (input_location, OPT_Wpedantic, 
                       "long, short, signed or unsigned used invalidly for %qs",
                       name);
              if (flag_pedantic_errors)
-               ok = 0;
+               ok = false;
            }
        }
 
@@ -9075,7 +9067,7 @@ grokdeclarator (const cp_declarator *declarator,
          signed_p = false;
          long_p = false;
          short_p = false;
-         longlong = 0;
+         longlong_p = false;
        }
     }
 
@@ -9090,7 +9082,7 @@ grokdeclarator (const cp_declarator *declarator,
 
         Naturally, we extend this to long long as well.  Note that
         this does not include wchar_t.  */
-      || (bitfield && !flag_signed_bitfields
+      || (bitfield_p && !flag_signed_bitfields
          && !signed_p
          /* A typedef for plain `int' without `signed' can be
             controlled just like plain `int', but a typedef for
@@ -9102,7 +9094,7 @@ grokdeclarator (const cp_declarator *declarator,
     {
       if (explicit_int128)
        type = int128_unsigned_type_node;
-      else if (longlong)
+      else if (longlong_p)
        type = long_long_unsigned_type_node;
       else if (long_p)
        type = long_unsigned_type_node;
@@ -9119,7 +9111,7 @@ grokdeclarator (const cp_declarator *declarator,
     type = signed_char_type_node;
   else if (explicit_int128)
     type = int128_integer_type_node;
-  else if (longlong)
+  else if (longlong_p)
     type = long_long_integer_type_node;
   else if (long_p)
     type = long_integer_type_node;
@@ -9134,7 +9126,7 @@ grokdeclarator (const cp_declarator *declarator,
         "complex double", but if any modifiers at all are specified it is
         the complex form of TYPE.  E.g, "complex short" is
         "complex short int".  */
-      else if (defaulted_int && ! longlong && ! explicit_int128
+      else if (defaulted_int && ! longlong_p && ! explicit_int128
               && ! (long_p || short_p || signed_p || unsigned_p))
        type = complex_double_type_node;
       else if (type == integer_type_node)
@@ -9149,7 +9141,8 @@ grokdeclarator (const cp_declarator *declarator,
        type = build_complex_type (type);
     }
 
-  type_quals = TYPE_UNQUALIFIED;
+  /* cv-qualifiers that apply to the type specified by the DECLSPECS.  */
+  int type_quals = TYPE_UNQUALIFIED;
   if (decl_spec_seq_has_spec_p (declspecs, ds_const))
     type_quals |= TYPE_QUAL_CONST;
   if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
@@ -9178,27 +9171,27 @@ grokdeclarator (const cp_declarator *declarator,
   /* We might have ignored or rejected some of the qualifiers.  */
   type_quals = cp_type_quals (type);
 
-  staticp = 0;
-  inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline);
-  virtualp =  decl_spec_seq_has_spec_p (declspecs, ds_virtual);
-  explicitp = decl_spec_seq_has_spec_p (declspecs, ds_explicit);
+  int staticv = 0;
+  int explicitv = decl_spec_seq_has_spec_p (declspecs, ds_explicit);
+  bool inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline);
+  bool virtualp = decl_spec_seq_has_spec_p (declspecs, ds_virtual);
+  bool friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
 
-  storage_class = declspecs->storage_class;
+  cp_storage_class storage_class = declspecs->storage_class;
   if (storage_class == sc_static)
-    staticp = 1 + (decl_context == FIELD);
+    staticv = 1 + (decl_context == FIELD);
 
-  if (virtualp && staticp == 2)
+  if (virtualp && staticv == 2)
     {
       error ("member %qD cannot be declared both virtual and static", dname);
       storage_class = sc_none;
-      staticp = 0;
+      staticv = 0;
     }
-  friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
 
   /* Issue errors about use of storage classes for parameters.  */
   if (decl_context == PARM)
     {
-      if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+      if (typedef_p)
        {
          error ("typedef declaration invalid in parameter declaration");
          return error_mark_node;
@@ -9218,7 +9211,7 @@ grokdeclarator (const cp_declarator *declarator,
       if (constexpr_p)
         {
           error ("a parameter cannot be declared %<constexpr%>");
-          constexpr_p = 0;
+          constexpr_p = false;
         }
     }
 
@@ -9227,11 +9220,11 @@ grokdeclarator (const cp_declarator *declarator,
       && (current_class_name == NULL_TREE || decl_context != FIELD))
     {
       error ("%<virtual%> outside class declaration");
-      virtualp = 0;
+      virtualp = false;
     }
 
   /* Static anonymous unions are dealt with here.  */
-  if (staticp && decl_context == TYPENAME
+  if (staticv && decl_context == TYPENAME
       && declspecs->type
       && ANON_AGGR_TYPE_P (declspecs->type))
     decl_context = FIELD;
@@ -9242,7 +9235,7 @@ grokdeclarator (const cp_declarator *declarator,
       && ((storage_class
           && storage_class != sc_extern
           && storage_class != sc_static)
-         || decl_spec_seq_has_spec_p (declspecs, ds_typedef)))
+         || typedef_p))
     {
       error ("multiple storage classes in declaration of %qs", name);
       thread_p = false;
@@ -9256,7 +9249,7 @@ grokdeclarator (const cp_declarator *declarator,
          && (storage_class == sc_register
              || storage_class == sc_auto))
        ;
-      else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+      else if (typedef_p)
        ;
       else if (decl_context == FIELD
               /* C++ allows static class elements.  */
@@ -9302,14 +9295,14 @@ grokdeclarator (const cp_declarator *declarator,
         storage-class-specifier static is implied if it does not appear
         explicitly.  */
       storage_class = declspecs->storage_class = sc_static;
-      staticp = 1;
+      staticv = 1;
     }
 
   if (storage_class && friendp)
     {
       error ("storage class specifiers invalid in friend function 
declarations");
       storage_class = sc_none;
-      staticp = 0;
+      staticv = 0;
     }
 
   if (!id_declarator)
@@ -9355,9 +9348,8 @@ grokdeclarator (const cp_declarator *declarator,
       attrs = declarator->attributes;
       if (attrs)
        {
-         int attr_flags;
+         int attr_flags = 0;
 
-         attr_flags = 0;
          if (declarator == NULL || declarator->kind == cdk_id)
            attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
          if (declarator->kind == cdk_function)
@@ -9390,9 +9382,6 @@ grokdeclarator (const cp_declarator *declarator,
 
        case cdk_function:
          {
-           tree arg_types;
-           int funcdecl_p;
-
            /* Declaring a function type.
               Make sure we have a valid type for the function to return.  */
 
@@ -9405,7 +9394,7 @@ grokdeclarator (const cp_declarator *declarator,
                   decl, but to its return type.  */
                type_quals = TYPE_UNQUALIFIED;
              }
-           errmsg = targetm.invalid_return_type (type);
+           const char *errmsg = targetm.invalid_return_type (type);
            if (errmsg)
              {
                error (errmsg);
@@ -9442,7 +9431,8 @@ grokdeclarator (const cp_declarator *declarator,
 
            /* Say it's a definition only for the CALL_EXPR
               closest to the identifier.  */
-           funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id;
+           bool funcdecl_p = (inner_declarator
+                              && inner_declarator->kind == cdk_id);
 
            /* Handle a late-specified return type.  */
            if (funcdecl_p)
@@ -9488,7 +9478,7 @@ grokdeclarator (const cp_declarator *declarator,
            if (ctype == NULL_TREE
                && decl_context == FIELD
                && funcdecl_p
-               && (friendp == 0 || dname == current_class_name))
+               && (! friendp || dname == current_class_name))
              ctype = current_class_type;
 
            if (ctype && (sfk == sfk_constructor
@@ -9506,7 +9496,7 @@ grokdeclarator (const cp_declarator *declarator,
                   ISO C++ 12.1.  A constructor may not be declared
                   const or volatile.  A constructor may not be
                   virtual.  A constructor may not be static.  */
-               if (staticp == 2)
+               if (staticv == 2)
                  error ((flags == DTOR_FLAG)
                         ? G_("destructor cannot be static member function")
                         : G_("constructor cannot be static member function"));
@@ -9527,19 +9517,20 @@ grokdeclarator (const cp_declarator *declarator,
                if (flags != DTOR_FLAG)
                  {
                    /* It's a constructor.  */
-                   if (explicitp == 1)
-                     explicitp = 2;
+                   if (explicitv == 1)
+                     explicitv = 2;
                    if (virtualp)
                      {
-                       permerror (input_location, "constructors cannot be 
declared virtual");
-                       virtualp = 0;
+                       permerror (input_location,
+                                  "constructors cannot be declared virtual");
+                       virtualp = false;
                      }
                    if (decl_context == FIELD
                        && sfk != sfk_constructor)
                      return error_mark_node;
                  }
                if (decl_context == FIELD)
-                 staticp = 0;
+                 staticv = 0;
              }
            else if (friendp)
              {
@@ -9549,7 +9540,7 @@ grokdeclarator (const cp_declarator *declarator,
                  {
                    /* Cannot be both friend and virtual.  */
                    error ("virtual functions cannot be friends");
-                   friendp = 0;
+                   friendp = false;
                  }
                if (decl_context == NORMAL)
                  error ("friend declaration not in class definition");
@@ -9560,15 +9551,15 @@ grokdeclarator (const cp_declarator *declarator,
              }
            else if (ctype && sfk == sfk_conversion)
              {
-               if (explicitp == 1)
+               if (explicitv == 1)
                  {
                    maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION);
-                   explicitp = 2;
+                   explicitv = 2;
                  }
              }
 
-           arg_types = grokparms (declarator->u.function.parameters,
-                                  &parms);
+           tree arg_types = grokparms (declarator->u.function.parameters,
+                                       &parms);
 
            if (inner_declarator
                && inner_declarator->kind == cdk_id
@@ -9823,8 +9814,9 @@ grokdeclarator (const cp_declarator *declarator,
        {
          if (friendp)
            {
-             permerror (input_location, "member functions are implicitly 
friends of their class");
-             friendp = 0;
+             permerror (input_location, "member functions are implicitly "
+                        "friends of their class");
+             friendp = false;
            }
          else
            permerror (declarator->id_loc, 
@@ -9866,8 +9858,7 @@ grokdeclarator (const cp_declarator *declarator,
              return error_mark_node;
            }
        }
-      else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)
-              && current_class_type)
+      else if (typedef_p && current_class_type)
        {
          error ("cannot declare member %<%T::%s%> within %qT",
                 ctype, name, current_class_type);
@@ -9875,7 +9866,7 @@ grokdeclarator (const cp_declarator *declarator,
        }
     }
 
-  if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
+  if (ctype == NULL_TREE && decl_context == FIELD && !friendp)
     ctype = current_class_type;
 
   /* Now TYPE has the actual type.  */
@@ -9929,12 +9920,12 @@ grokdeclarator (const cp_declarator *declarator,
       type = error_mark_node;
     }
 
-  if (explicitp == 1 || (explicitp && friendp))
+  if (explicitv == 1 || (explicitv && friendp))
     {
       /* [dcl.fct.spec] The explicit specifier shall only be used in
         declarations of constructors within a class definition.  */
       error ("only declarations of constructors can be %<explicit%>");
-      explicitp = 0;
+      explicitv = 0;
     }
 
   if (storage_class == sc_mutable)
@@ -9944,8 +9935,7 @@ grokdeclarator (const cp_declarator *declarator,
          error ("non-member %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
        }
-      else if (decl_context == TYPENAME
-              || decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+      else if (decl_context == TYPENAME || typedef_p)
        {
          error ("non-object member %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
@@ -9956,7 +9946,7 @@ grokdeclarator (const cp_declarator *declarator,
          error ("function %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
        }
-      else if (staticp)
+      else if (staticv)
        {
          error ("static %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
@@ -9975,7 +9965,7 @@ grokdeclarator (const cp_declarator *declarator,
     }
 
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
-  if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) && decl_context != 
TYPENAME)
+  if (typedef_p && decl_context != TYPENAME)
     {
       tree decl;
 
@@ -10032,9 +10022,8 @@ grokdeclarator (const cp_declarator *declarator,
        }
       else if (current_class_type
               && constructor_name_p (unqualified_id, current_class_type))
-       permerror (input_location, "ISO C++ forbids nested type %qD with same 
name "
-                  "as enclosing class",
-                  unqualified_id);
+       permerror (input_location, "ISO C++ forbids nested type %qD with "
+                  "same name as enclosing class", unqualified_id);
 
       /* If the user declares "typedef struct {...} foo" then the
         struct will have an anonymous name.  Fill that name in now.
@@ -10048,10 +10037,8 @@ grokdeclarator (const cp_declarator *declarator,
          && declspecs->type_definition_p
          && cp_type_quals (type) == TYPE_UNQUALIFIED)
        {
-         tree t;
-
          /* Replace the anonymous name with the real name everywhere.  */
-         for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+         for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
            {
              if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
                /* We do not rename the debug info representing the
@@ -10111,9 +10098,8 @@ grokdeclarator (const cp_declarator *declarator,
   if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE)
     {
       tree decls = NULL_TREE;
-      tree args;
 
-      for (args = TYPE_ARG_TYPES (type);
+      for (tree args = TYPE_ARG_TYPES (type);
           args && args != void_list_node;
           args = TREE_CHAIN (args))
        {
@@ -10130,9 +10116,9 @@ grokdeclarator (const cp_declarator *declarator,
          /* A cv-qualifier-seq shall only be part of the function type
             for a non-static member function. [8.3.5/4 dcl.fct] */
          if (type_memfn_quals (type) != TYPE_UNQUALIFIED
-             && (current_class_type == NULL_TREE || staticp) )
+             && (current_class_type == NULL_TREE || staticv) )
            {
-             error (staticp
+             error (staticv
                      ? G_("qualified function types cannot be used to "
                           "declare static member functions")
                      : G_("qualified function types cannot be used to "
@@ -10168,22 +10154,22 @@ grokdeclarator (const cp_declarator *declarator,
          if (inlinep)
            {
              error ("%<inline%> specified for friend class declaration");
-             inlinep = 0;
+             inlinep = false;
            }
 
          if (!current_aggr)
            {
              /* Don't allow friend declaration without a class-key.  */
              if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
-               permerror (input_location, "template parameters cannot be 
friends");
+               permerror (input_location,
+                          "template parameters cannot be friends");
              else if (TREE_CODE (type) == TYPENAME_TYPE)
-               permerror (input_location, "friend declaration requires 
class-key, "
-                          "i.e. %<friend class %T::%D%>",
+               permerror (input_location, "friend declaration requires "
+                          "class-key, i.e. %<friend class %T::%D%>",
                           TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
              else
-               permerror (input_location, "friend declaration requires 
class-key, "
-                          "i.e. %<friend %#T%>",
-                          type);
+               permerror (input_location, "friend declaration requires "
+                          "class-key, i.e. %<friend %#T%>", type);
            }
 
          /* Only try to do this stuff if we didn't already give up.  */
@@ -10220,7 +10206,7 @@ grokdeclarator (const cp_declarator *declarator,
   else if (unqualified_id == NULL_TREE && decl_context != PARM
           && decl_context != CATCHPARM
           && TREE_CODE (type) != UNION_TYPE
-          && ! bitfield)
+          && ! bitfield_p)
     {
       error ("abstract declarator %qT used as declaration", type);
       return error_mark_node;
@@ -10273,7 +10259,7 @@ grokdeclarator (const cp_declarator *declarator,
        type = build_pointer_type (type);
     }
 
-  if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
+  if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticv < 2
       && !NEW_DELETE_OPNAME_P (unqualified_id))
     {
       cp_cv_quals real_quals = memfn_quals;
@@ -10295,7 +10281,7 @@ grokdeclarator (const cp_declarator *declarator,
       }
     else if (decl_context == FIELD)
       {
-       if (!staticp && TREE_CODE (type) != METHOD_TYPE
+       if (!staticv && TREE_CODE (type) != METHOD_TYPE
            && type_uses_auto (type))
          {
            error ("non-static data member declared %<auto%>");
@@ -10303,7 +10289,7 @@ grokdeclarator (const cp_declarator *declarator,
          }
 
        /* The C99 flexible array extension.  */
-       if (!staticp && TREE_CODE (type) == ARRAY_TYPE
+       if (!staticv && TREE_CODE (type) == ARRAY_TYPE
            && TYPE_DOMAIN (type) == NULL_TREE)
          {
            tree itype = compute_array_index_type (dname, integer_zero_node,
@@ -10326,10 +10312,9 @@ grokdeclarator (const cp_declarator *declarator,
        else if (TREE_CODE (type) == FUNCTION_TYPE
                 || TREE_CODE (type) == METHOD_TYPE)
          {
-           int publicp = 0;
            tree function_context;
 
-           if (friendp == 0)
+           if (!friendp)
              {
                /* This should never happen in pure C++ (the check
                   could be an assert).  It could happen in
@@ -10363,7 +10348,7 @@ grokdeclarator (const cp_declarator *declarator,
                        error ("%qD cannot be declared virtual, since it "
                               "is always static",
                               unqualified_id);
-                       virtualp = 0;
+                       virtualp = false;
                      }
                  }
              }
@@ -10404,8 +10389,8 @@ grokdeclarator (const cp_declarator *declarator,
            /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node.  */
            function_context = (ctype != NULL_TREE) ?
              decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
-           publicp = (! friendp || ! staticp)
-             && function_context == NULL_TREE;
+           bool publicp = ((! friendp || ! staticv)
+                           && function_context == NULL_TREE);
            decl = grokfndecl (ctype, type,
                               TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR
                               ? unqualified_id : dname,
@@ -10413,7 +10398,7 @@ grokdeclarator (const cp_declarator *declarator,
                               unqualified_id,
                               virtualp, flags, memfn_quals, raises,
                               friendp ? -1 : 0, friendp, publicp,
-                               inlinep | (2 * constexpr_p),
+                               inlinep, constexpr_p,
                               sfk,
                               funcdef_flag, template_count, in_namespace,
                               attrlist, declarator->id_loc);
@@ -10433,10 +10418,10 @@ grokdeclarator (const cp_declarator *declarator,
               specifies a conversion from the type of its first
               parameter to the type of its class.  Such a constructor
               is called a converting constructor.  */
-           if (explicitp == 2)
+           if (explicitv == 2)
              DECL_NONCONVERTING_P (decl) = 1;
          }
-       else if (!staticp && !dependent_type_p (type)
+       else if (!staticv && !dependent_type_p (type)
                 && !COMPLETE_TYPE_P (complete_type (type))
                 && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
          {
@@ -10463,7 +10448,7 @@ grokdeclarator (const cp_declarator *declarator,
              {
                error ("%qE is neither function nor member function; "
                       "cannot be declared friend", unqualified_id);
-               friendp = 0;
+               friendp = false;
              }
            decl = NULL_TREE;
          }
@@ -10497,7 +10482,7 @@ grokdeclarator (const cp_declarator *declarator,
 
        if (decl == NULL_TREE)
          {
-           if (staticp)
+           if (staticv)
              {
                /* C++ allows static class members.  All other work
                   for this is done by grokfield.  */
@@ -10533,8 +10518,8 @@ grokdeclarator (const cp_declarator *declarator,
                  }
                decl = build_decl (input_location,
                                   FIELD_DECL, unqualified_id, type);
-               DECL_NONADDRESSABLE_P (decl) = bitfield;
-               if (bitfield && !unqualified_id)
+               DECL_NONADDRESSABLE_P (decl) = bitfield_p;
+               if (bitfield_p && !unqualified_id)
                  TREE_NO_WARNING (decl) = 1;
 
                if (storage_class == sc_mutable)
@@ -10550,7 +10535,7 @@ grokdeclarator (const cp_declarator *declarator,
                    maybe_warn_cpp0x (CPP0X_NSDMI);
 
                    /* If this has been parsed with static storage class, but
-                      errors forced staticp to be cleared, ensure NSDMI is
+                      errors forced staticv to be cleared, ensure NSDMI is
                       not present.  */
                    if (declspecs->storage_class == sc_static)
                      DECL_INITIAL (decl) = error_mark_node;
@@ -10566,7 +10551,6 @@ grokdeclarator (const cp_declarator *declarator,
             || TREE_CODE (type) == METHOD_TYPE)
       {
        tree original_name;
-       int publicp = 0;
 
        if (!unqualified_id)
          return error_mark_node;
@@ -10591,7 +10575,8 @@ grokdeclarator (const cp_declarator *declarator,
          }
 
         if (virt_specifiers)
-          error ("virt-specifiers in %qs not allowed outside a class 
definition", name);
+          error ("virt-specifiers in %qs not allowed outside a class "
+                "definition", name);
        /* Function declaration not at top level.
           Storage classes other than `extern' are not allowed
           and `extern' makes no difference.  */
@@ -10615,7 +10600,7 @@ grokdeclarator (const cp_declarator *declarator,
            if (virtualp)
              {
                error ("virtual non-class function %qs", name);
-               virtualp = 0;
+               virtualp = false;
              }
            else if (sfk == sfk_constructor
                     || sfk == sfk_destructor)
@@ -10628,41 +10613,42 @@ grokdeclarator (const cp_declarator *declarator,
          }
 
        /* Record whether the function is public.  */
-       publicp = (ctype != NULL_TREE
-                  || storage_class != sc_static);
+       bool publicp = (ctype != NULL_TREE
+                       || storage_class != sc_static);
 
        decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
                           virtualp, flags, memfn_quals, raises,
                           1, friendp,
-                          publicp, inlinep | (2 * constexpr_p), sfk,
+                          publicp, inlinep, constexpr_p, sfk,
                            funcdef_flag,
                           template_count, in_namespace, attrlist,
                           declarator->id_loc);
        if (decl == NULL_TREE)
          return error_mark_node;
 
-       if (staticp == 1)
+       if (staticv == 1)
          {
-           int invalid_static = 0;
+           bool invalid_static = false;
 
            /* Don't allow a static member function in a class, and forbid
               declaring main to be static.  */
            if (TREE_CODE (type) == METHOD_TYPE)
              {
-               permerror (input_location, "cannot declare member function %qD 
to have "
-                          "static linkage", decl);
-               invalid_static = 1;
+               permerror (input_location, "cannot declare member function %qD "
+                          "to have static linkage", decl);
+               invalid_static = true;
              }
            else if (current_function_decl)
              {
                /* FIXME need arm citation */
-               error ("cannot declare static function inside another 
function");
-               invalid_static = 1;
+               error ("cannot declare static function inside another "
+                      "function");
+               invalid_static = true;
              }
 
            if (invalid_static)
              {
-               staticp = 0;
+               staticv = 0;
                storage_class = sc_none;
              }
          }
@@ -10684,11 +10670,12 @@ grokdeclarator (const cp_declarator *declarator,
        if (ctype)
          {
            DECL_CONTEXT (decl) = ctype;
-           if (staticp == 1)
+           if (staticv == 1)
              {
-               permerror (input_location, "%<static%> may not be used when 
defining "
+               permerror (input_location,
+                          "%<static%> may not be used when defining "
                           "(as opposed to declaring) a static data member");
-               staticp = 0;
+               staticv = 0;
                storage_class = sc_none;
              }
            if (storage_class == sc_register && TREE_STATIC (decl))
Index: testsuite/g++.dg/cpp0x/constexpr-friend-2.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-friend-2.C (revision 0)
+++ testsuite/g++.dg/cpp0x/constexpr-friend-2.C (working copy)
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++11 } }
+
+template<typename T> void f(T);
+
+template <class T> class A {
+  friend constexpr void f<>(int);  // { dg-error "'constexpr' is not allowed" }
+};
Index: testsuite/g++.dg/cpp0x/constexpr-main.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-main.C     (revision 0)
+++ testsuite/g++.dg/cpp0x/constexpr-main.C     (working copy)
@@ -0,0 +1,3 @@
+// { dg-do compile { target c++11 } }
+
+constexpr int main ();  // { dg-error "constexpr" }

Reply via email to