Patchwork [C++] Clean-up a bit grokdeclarator

login
register
mail settings
Submitter Paolo Carlini
Date March 20, 2013, 12:30 a.m.
Message ID <51490336.7000509@oracle.com>
Download mbox | patch
Permalink /patch/229236/
State New
Headers show

Comments

Paolo Carlini - March 20, 2013, 12:30 a.m.
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.carlini@oracle.com>

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

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

	* g++.dg/cpp0x/constexpr-friend-2.C: New.
	* g++.dg/cpp0x/constexpr-main.C: Likewise.

Patch

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" }