tree inner_parms = TREE_OPERAND (declarator, 1);
tree inner_parms = CALL_DECLARATOR_PARMS (declarator);
grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)     tree declspecs;     tree declarator;     enum decl_context decl_context;     int initialized;     tree attrlist;{  RID_BIT_TYPE specbits;  int nclasses = 0;  tree spec;  tree type = NULL_TREE;  int longlong = 0;  int constp;  int restrictp;  int volatilep;  int type_quals;  int virtualp, explicitp, friendp, inlinep, staticp;  int explicit_int = 0;  int explicit_char = 0;  int defaulted_int = 0;  int opaque_typedef = 0;  tree typedef_decl = NULL_TREE;  char *name;  tree typedef_type = NULL_TREE;  int funcdef_flag = 0;  enum tree_code innermost_code = ERROR_MARK;  int bitfield = 0;#if 0  /* See the code below that used this.  */  tree decl_machine_attr = NULL_TREE;#endif  /* Set this to error_mark_node for FIELD_DECLs we could not handle properly.     All FIELD_DECLs we build here have `init' put into their DECL_INITIAL.  */  tree init = NULL_TREE;  /* Keep track of what sort of function is being processed     so that we can warn about default return values, or explicit     return values which do not match prescribed defaults.  */  enum return_types return_type = return_normal;  tree dname = NULL_TREE;  tree ctype = current_class_type;  tree ctor_return_type = NULL_TREE;  enum overload_flags flags = NO_SPECIAL;  tree quals = NULL_TREE;  tree raises = NULL_TREE;  int template_count = 0;  tree in_namespace = NULL_TREE;  tree inner_attrs;  int ignore_attrs;  RIDBIT_RESET_ALL (specbits);  if (decl_context == FUNCDEF)    funcdef_flag = 1, decl_context = NORMAL;  else if (decl_context == MEMFUNCDEF)    funcdef_flag = -1, decl_context = FIELD;  else if (decl_context == BITFIELD)    bitfield = 1, decl_context = FIELD;  /* Look inside a declarator for the name being declared     and get it as a string, for an error message.  */  {    tree *next = &declarator;    register tree decl;    name = NULL;    while (next && *next)      {	decl = *next;	switch (TREE_CODE (decl))	  {	  case TREE_LIST:	    /* For attributes.  */	    next = &TREE_VALUE (decl);	    break;	  case COND_EXPR:	    ctype = NULL_TREE;	    next = &TREE_OPERAND (decl, 0);	    break;	  case BIT_NOT_EXPR:	/* For C++ destructors!  */	    {	      tree name = TREE_OPERAND (decl, 0);	      tree rename = NULL_TREE;	      my_friendly_assert (flags == NO_SPECIAL, 152);	      flags = DTOR_FLAG;	      return_type = return_dtor;	      if (TREE_CODE (name) == TYPE_DECL)		TREE_OPERAND (decl, 0) = name = constructor_name (name);	      my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);	      if (ctype == NULL_TREE)		{		  if (current_class_type == NULL_TREE)		    {		      error ("destructors must be member functions");		      flags = NO_SPECIAL;		    }		  else		    {		      tree t = constructor_name (current_class_name);		      if (t != name)			rename = t;		    }		}	      else		{		  tree t = constructor_name (ctype);		  if (t != name)		    rename = t;		}	      if (rename)		{		  cp_error ("destructor `%T' must match class name `%T'",			    name, rename);		  TREE_OPERAND (decl, 0) = rename;		}	      next = &name;	    }	    break;	  case ADDR_EXPR:	/* C++ reference declaration */	    /* Fall through. */	  case ARRAY_REF:	  case INDIRECT_REF:	    ctype = NULL_TREE;	    innermost_code = TREE_CODE (decl);	    next = &TREE_OPERAND (decl, 0);	    break;	  case CALL_EXPR:	    if (parmlist_is_exprlist (TREE_OPERAND (decl, 1)))	      {		/* This is actually a variable declaration using		   constructor syntax.  We need to call start_decl and		   cp_finish_decl so we can get the variable		   initialized...  */		tree attributes, prefix_attributes;		*next = TREE_OPERAND (decl, 0);		init = TREE_OPERAND (decl, 1);		if (attrlist)		  {		    attributes = TREE_PURPOSE (attrlist);		    prefix_attributes = TREE_VALUE (attrlist);		  }		else		  {		    attributes = NULL_TREE;		    prefix_attributes = NULL_TREE;		  }		decl = start_decl (declarator, declspecs, 1,				   attributes, prefix_attributes);		if (decl)		  {		    /* Look for __unused__ attribute */		    if (TREE_USED (TREE_TYPE (decl)))		      TREE_USED (decl) = 1;		    finish_decl (decl, init, NULL_TREE);		  }		else		  cp_error ("invalid declarator");		return 0;	      }	    innermost_code = TREE_CODE (decl);	    if (decl_context == FIELD && ctype == NULL_TREE)	      ctype = current_class_type;	    if (ctype		&& TREE_OPERAND (decl, 0)		&& (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL		    && ((DECL_NAME (TREE_OPERAND (decl, 0))			 == constructor_name_full (ctype))			|| (DECL_NAME (TREE_OPERAND (decl, 0))			    == constructor_name (ctype)))))	      TREE_OPERAND (decl, 0) = constructor_name (ctype);	    next = &TREE_OPERAND (decl, 0);	    decl = *next;	    if (ctype != NULL_TREE		&& decl != NULL_TREE && flags != DTOR_FLAG		&& decl == constructor_name (ctype))	      {		return_type = return_ctor;		ctor_return_type = ctype;	      }	    ctype = NULL_TREE;	    break;	    	  case TEMPLATE_ID_EXPR:	      {		tree fns = TREE_OPERAND (decl, 0);		if (TREE_CODE (fns) == LOOKUP_EXPR)		  fns = TREE_OPERAND (fns, 0);		dname = fns;		if (TREE_CODE (dname) == COMPONENT_REF)		  dname = TREE_OPERAND (dname, 1);		if (TREE_CODE (dname) != IDENTIFIER_NODE)		  {		    my_friendly_assert (is_overloaded_fn (dname),					19990331);		    dname = DECL_NAME (get_first_fn (dname));		  }	      }	  /* Fall through. */	  case IDENTIFIER_NODE:	    if (TREE_CODE (decl) == IDENTIFIER_NODE)	      dname = decl;	    next = 0;	    if (is_rid (dname))	      {		cp_error ("declarator-id missing; using reserved word `%D'",			  dname);		name = IDENTIFIER_POINTER (dname);	      }	    if (! IDENTIFIER_OPNAME_P (dname)		/* GNU/Linux headers use '__op'.  Arrgh.  */		|| (IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname)))	      name = IDENTIFIER_POINTER (dname);	    else	      {		if (IDENTIFIER_TYPENAME_P (dname))		  {		    my_friendly_assert (flags == NO_SPECIAL, 154);		    flags = TYPENAME_FLAG;		    ctor_return_type = TREE_TYPE (dname);		    return_type = return_conversion;		  }		name = operator_name_string (dname);	      }	    break;	    /* C++ extension */	  case SCOPE_REF:	    {	      /* Perform error checking, and decide on a ctype.  */	      tree cname = TREE_OPERAND (decl, 0);	      if (cname == NULL_TREE)		ctype = NULL_TREE;	      else if (TREE_CODE (cname) == NAMESPACE_DECL)		{		  ctype = NULL_TREE;		  in_namespace = TREE_OPERAND (decl, 0);		  TREE_OPERAND (decl, 0) = NULL_TREE;		}	      else if (! is_aggr_type (cname, 1))		TREE_OPERAND (decl, 0) = NULL_TREE;	      /* Must test TREE_OPERAND (decl, 1), in case user gives		 us `typedef (class::memfunc)(int); memfunc *memfuncptr;'  */	      else if (TREE_OPERAND (decl, 1)		       && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)		ctype = cname;	      else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM		       || TREE_CODE (cname) == TEMPLATE_TEMPLATE_PARM)		{		  cp_error ("`%T::%D' is not a valid declarator", cname,			    TREE_OPERAND (decl, 1));		  cp_error ("  perhaps you want `typename %T::%D' to make it a type",			    cname, TREE_OPERAND (decl, 1));		  return void_type_node;		}	      else if (ctype == NULL_TREE)		ctype = cname;	      else if (TREE_COMPLEXITY (decl) == current_class_depth)		TREE_OPERAND (decl, 0) = ctype;	      else		{		  if (! UNIQUELY_DERIVED_FROM_P (cname, ctype))		    {		      cp_error ("type `%T' is not derived from type `%T'",				cname, ctype);		      TREE_OPERAND (decl, 0) = NULL_TREE;		    }		  else		    ctype = cname;		}	      if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL		  && ((DECL_NAME (TREE_OPERAND (decl, 1))		       == constructor_name_full (ctype))		      || (DECL_NAME (TREE_OPERAND (decl, 1))			  == constructor_name (ctype))))		TREE_OPERAND (decl, 1) = constructor_name (ctype);	      next = &TREE_OPERAND (decl, 1);	      decl = *next;	      if (ctype)		{		  if (TREE_CODE (decl) == IDENTIFIER_NODE		      && constructor_name (ctype) == decl)		    {		      return_type = return_ctor;		      ctor_return_type = ctype;		    }		  else if (TREE_CODE (decl) == BIT_NOT_EXPR			   && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE			   && (constructor_name (ctype) == TREE_OPERAND (decl, 0)			       || constructor_name_full (ctype) == TREE_OPERAND (decl, 0)))		    {		      return_type = return_dtor;		      ctor_return_type = ctype;		      flags = DTOR_FLAG;		      TREE_OPERAND (decl, 0) = constructor_name (ctype);		      next = &TREE_OPERAND (decl, 0);		    }		}	    }	    break;	  case ERROR_MARK:	    next = 0;	    break;	  case TYPE_DECL:	    /* Parse error puts this typespec where	       a declarator should go.  */	    cp_error ("`%T' specified as declarator-id", DECL_NAME (decl));	    if (TREE_TYPE (decl) == current_class_type)	      cp_error ("  perhaps you want `%T' for a constructor",			current_class_name);	    dname = DECL_NAME (decl);	    name = IDENTIFIER_POINTER (dname);	    /* Avoid giving two errors for this.  */	    IDENTIFIER_CLASS_VALUE (dname) = NULL_TREE;	    declspecs = temp_tree_cons (NULL_TREE, integer_type_node,					declspecs);	    *next = dname;	    next = 0;	    break;	  default:	    cp_compiler_error ("`%D' as declarator", decl);	    return 0; /* We used to do a 155 abort here.  */	  }      }    if (name == NULL)      name = "type name";  }  /* A function definition's declarator must have the form of     a function declarator.  */  if (funcdef_flag && innermost_code != CALL_EXPR)    return 0;  if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)      && innermost_code != CALL_EXPR      && ! (ctype && declspecs == NULL_TREE))    {      cp_error ("declaration of `%D' as non-function", dname);      return void_type_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).  */  /* This heuristic cannot be applied to C++ nodes! Fixed, however,     by not allowing C++ class definitions to specify their parameters     with xdecls (must be spec.d in the parmlist).     Since we now wait to push a class scope until we are sure that     we are in a legitimate method context, we must set oldcname     explicitly (since current_class_name is not yet alive).     We also want to avoid calling this a PARM if it is in a namespace.  */  if (decl_context == NORMAL && ! namespace_bindings_p ()      && ! pseudo_global_level_p ())    {      struct binding_level *b = current_binding_level;      current_binding_level = b->level_chain;      if (current_binding_level != 0 && toplevel_bindings_p ())	decl_context = PARM;      current_binding_level = b;    }  /* Look through the decl specs and record which ones appear.     Some typespecs are defined as built-in typenames.     Others, the ones that are modifiers of other types,     are represented by bits in SPECBITS: set the bits for     the modifiers that appear.  Storage class keywords are also in SPECBITS.     If there is a typedef name or a type, store the type in TYPE.     This includes builtin typedefs such as `int'.     Set EXPLICIT_INT if the type is `int' or `char' and did not     come from a user typedef.     Set LONGLONG if `long' is mentioned twice.     For C++, constructors and destructors have their own fast treatment.  */  for (spec = declspecs; spec; spec = TREE_CHAIN (spec))    {      register int i;      register tree id;      /* Certain parse errors slip through.  For example,	 `int class;' is not caught by the parser. Try	 weakly to recover here.  */      if (TREE_CODE (spec) != TREE_LIST)	return 0;      id = TREE_VALUE (spec);      if (TREE_CODE (id) == IDENTIFIER_NODE)	{	  if (id == ridpointers[(int) RID_INT]	      || id == ridpointers[(int) RID_CHAR]	      || id == ridpointers[(int) RID_BOOL]	      || id == ridpointers[(int) RID_WCHAR])	    {	      if (type)		{		  if (id == ridpointers[(int) RID_BOOL])		    error ("`bool' is now a keyword");		  else		    cp_error ("extraneous `%T' ignored", id);		}	      else		{		  if (id == ridpointers[(int) RID_INT])		    explicit_int = 1;		  else if (id == ridpointers[(int) RID_CHAR])		    explicit_char = 1;		  type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));		}	      goto found;	    }	  /* C++ aggregate types.  */	  if (IDENTIFIER_HAS_TYPE_VALUE (id))	    {	      if (type)		cp_error ("multiple declarations `%T' and `%T'", type, id);	      else		type = IDENTIFIER_TYPE_VALUE (id);	      goto found;	    }	  for (i = (int) RID_FIRST_MODIFIER; i <= (int) RID_LAST_MODIFIER; i++)	    {	      if (ridpointers[i] == id)		{		  if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits))		    {		      if (pedantic && ! in_system_header && warn_long_long)			pedwarn ("ANSI C++ does not support `long long'");		      if (longlong)			error ("`long long long' is too long for GCC");		      else			longlong = 1;		    }		  else if (RIDBIT_SETP (i, specbits))		    pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));		  RIDBIT_SET (i, specbits);		  goto found;		}	    }	}      /* C++ aggregate types.  */      else if (TREE_CODE (id) == TYPE_DECL || TREE_CODE (id) == TEMPLATE_DECL)	{	  if (type)	    cp_error ("multiple declarations `%T' and `%T'", type,		      TREE_TYPE (id));	  else	    {	      type = TREE_TYPE (id);	      TREE_VALUE (spec) = type;	    }	  goto found;	}      if (type)	error ("two or more data types in declaration of `%s'", name);      else if (TREE_CODE (id) == IDENTIFIER_NODE)	{	  register tree t = lookup_name (id, 1);	  if (!t || TREE_CODE (t) != TYPE_DECL)	    error ("`%s' fails to be a typedef or built in type",		   IDENTIFIER_POINTER (id));	  else	    {	      type = TREE_TYPE (t);#if 0	      /* See the code below that used this.  */	      decl_machine_attr = DECL_MACHINE_ATTRIBUTES (id);#endif	      typedef_decl = t;	    }	}      else if (id != error_mark_node)	/* Can't change CLASS nodes into RECORD nodes here!  */	type = id;    found: ;    }  typedef_type = type;  /* No type at all: default to `int', and set DEFAULTED_INT     because it was not a user-defined typedef.     Except when we have a `typedef' inside a signature, in     which case the type defaults to `unknown type' and is     instantiated when assigning to a signature pointer or ref.  */  if (type == NULL_TREE      && (RIDBIT_SETP (RID_SIGNED, specbits)	  || RIDBIT_SETP (RID_UNSIGNED, specbits)	  || RIDBIT_SETP (RID_LONG, specbits)	  || RIDBIT_SETP (RID_SHORT, specbits)))    {      /* These imply 'int'.  */      type = integer_type_node;      defaulted_int = 1;    }  if (type == NULL_TREE)    {      explicit_int = -1;      if (return_type == return_dtor)	type = void_type_node;      else if (return_type == return_ctor)	type = build_pointer_type (ctor_return_type);      else if (return_type == return_conversion)	type = ctor_return_type;      else if (current_class_type	       && IS_SIGNATURE (current_class_type)	       && RIDBIT_SETP (RID_TYPEDEF, specbits)	       && (decl_context == FIELD || decl_context == NORMAL))	{	  explicit_int = 0;	  opaque_typedef = 1;	  type = copy_node (opaque_type_node);	}      else	{	  /* 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.  */	  int is_main = (funcdef_flag			 && MAIN_NAME_P (dname)			 && ctype == NULL_TREE			 && in_namespace == NULL_TREE			 && current_namespace == global_namespace);	  if (in_system_header)	    /* Allow it, sigh.  */;	  else if (pedantic || ! is_main)	    cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type",			dname);	  else if (warn_return_type)	    cp_warning ("ANSI C++ forbids declaration `%D' with no type",			dname);	  type = integer_type_node;	}    }  else if (return_type == return_dtor)    {      error ("return type specification for destructor invalid");      type = void_type_node;    }  else if (return_type == return_ctor)    {      error ("return type specification for constructor invalid");      type = build_pointer_type (ctor_return_type);    }  else if (return_type == return_conversion)    {      if (!same_type_p (type, ctor_return_type))	cp_error ("operator `%T' declared to return `%T'",		  ctor_return_type, type);      else	cp_pedwarn ("return type specified for `operator %T'",		    ctor_return_type);      type = ctor_return_type;    }  ctype = NULL_TREE;  /* Now process the modifiers that were specified     and check for invalid combinations.  */  /* Long double is a special combination.  */  if (RIDBIT_SETP (RID_LONG, specbits)      && TYPE_MAIN_VARIANT (type) == double_type_node)    {      RIDBIT_RESET (RID_LONG, specbits);      type = build_qualified_type (long_double_type_node, 				   CP_TYPE_QUALS (type));    }  /* Check all other uses of type modifiers.  */  if (RIDBIT_SETP (RID_UNSIGNED, specbits)      || RIDBIT_SETP (RID_SIGNED, specbits)      || RIDBIT_SETP (RID_LONG, specbits)      || RIDBIT_SETP (RID_SHORT, specbits))    {      int ok = 0;      if (TREE_CODE (type) == REAL_TYPE)	error ("short, signed or unsigned invalid for `%s'", name);      else if (TREE_CODE (type) != INTEGER_TYPE)	error ("long, short, signed or unsigned invalid for `%s'", name);      else if (RIDBIT_SETP (RID_LONG, specbits)	       && RIDBIT_SETP (RID_SHORT, specbits))	error ("long and short specified together for `%s'", name);      else if ((RIDBIT_SETP (RID_LONG, specbits)		|| RIDBIT_SETP (RID_SHORT, specbits))	       && explicit_char)	error ("long or short specified with char for `%s'", name);      else if ((RIDBIT_SETP (RID_LONG, specbits)		|| RIDBIT_SETP (RID_SHORT, specbits))	       && TREE_CODE (type) == REAL_TYPE)	error ("long or short specified with floating type for `%s'", name);      else if (RIDBIT_SETP (RID_SIGNED, specbits)	       && RIDBIT_SETP (RID_UNSIGNED, specbits))	error ("signed and unsigned given together for `%s'", name);      else	{	  ok = 1;	  if (!explicit_int && !defaulted_int && !explicit_char && pedantic)	    {	      pedwarn ("long, short, signed or unsigned used invalidly for `%s'",		       name);	      if (flag_pedantic_errors)		ok = 0;	    }	}      /* Discard the type modifiers if they are invalid.  */      if (! ok)	{	  RIDBIT_RESET (RID_UNSIGNED, specbits);	  RIDBIT_RESET (RID_SIGNED, specbits);	  RIDBIT_RESET (RID_LONG, specbits);	  RIDBIT_RESET (RID_SHORT, specbits);	  longlong = 0;	}    }  if (RIDBIT_SETP (RID_COMPLEX, specbits)      && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)    {      error ("complex invalid for `%s'", name);      RIDBIT_RESET (RID_COMPLEX, specbits);    }  /* Decide whether an integer type is signed or not.     Optionally treat bitfields as signed by default.  */  if (RIDBIT_SETP (RID_UNSIGNED, specbits)      || (bitfield && ! flag_signed_bitfields	  && (explicit_int || defaulted_int || explicit_char	      /* A typedef for plain `int' without `signed'		 can be controlled just like plain `int'.  */	      || ! (typedef_decl != NULL_TREE		    && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))	  && TREE_CODE (type) != ENUMERAL_TYPE	  && RIDBIT_NOTSETP (RID_SIGNED, specbits)))    {      if (longlong)	type = long_long_unsigned_type_node;      else if (RIDBIT_SETP (RID_LONG, specbits))	type = long_unsigned_type_node;      else if (RIDBIT_SETP (RID_SHORT, specbits))	type = short_unsigned_type_node;      else if (type == char_type_node)	type = unsigned_char_type_node;      else if (typedef_decl)	type = unsigned_type (type);      else	type = unsigned_type_node;    }  else if (RIDBIT_SETP (RID_SIGNED, specbits)	   && type == char_type_node)    type = signed_char_type_node;  else if (longlong)    type = long_long_integer_type_node;  else if (RIDBIT_SETP (RID_LONG, specbits))    type = long_integer_type_node;  else if (RIDBIT_SETP (RID_SHORT, specbits))    type = short_integer_type_node;  if (RIDBIT_SETP (RID_COMPLEX, specbits))    {      /* If we just have "complex", it is equivalent to	 "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".  */      if (defaulted_int && ! longlong	  && ! (RIDBIT_SETP (RID_LONG, specbits)		|| RIDBIT_SETP (RID_SHORT, specbits)		|| RIDBIT_SETP (RID_SIGNED, specbits)		|| RIDBIT_SETP (RID_UNSIGNED, specbits)))	type = complex_double_type_node;      else if (type == integer_type_node)	type = complex_integer_type_node;      else if (type == float_type_node)	type = complex_float_type_node;      else if (type == double_type_node)	type = complex_double_type_node;      else if (type == long_double_type_node)	type = complex_long_double_type_node;      else	type = build_complex_type (type);    }  if (return_type == return_conversion       && (RIDBIT_SETP (RID_CONST, specbits)	  || RIDBIT_SETP (RID_VOLATILE, specbits)	  || RIDBIT_SETP (RID_RESTRICT, specbits)))    cp_error ("qualifiers are not allowed on declaration of `operator %T'",	      ctor_return_type);  /* Set CONSTP if this declaration is `const', whether by     explicit specification or via a typedef.     Likewise for VOLATILEP.  */  constp = !! RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_CONST_P (type);  restrictp =     !! RIDBIT_SETP (RID_RESTRICT, specbits) + CP_TYPE_RESTRICT_P (type);  volatilep =     !! RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE_P (type);  type_quals = ((constp ? TYPE_QUAL_CONST : 0)		| (restrictp ? TYPE_QUAL_RESTRICT : 0)		| (volatilep ? TYPE_QUAL_VOLATILE : 0));  type = cp_build_qualified_type (type, type_quals);  staticp = 0;  inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);  virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);  RIDBIT_RESET (RID_VIRTUAL, specbits);  explicitp = RIDBIT_SETP (RID_EXPLICIT, specbits) != 0;  RIDBIT_RESET (RID_EXPLICIT, specbits);  if (RIDBIT_SETP (RID_STATIC, specbits))    staticp = 1 + (decl_context == FIELD);  if (virtualp && staticp == 2)    {      cp_error ("member `%D' cannot be declared both virtual and static",		dname);      staticp = 0;    }  friendp = RIDBIT_SETP (RID_FRIEND, specbits);  RIDBIT_RESET (RID_FRIEND, specbits);  /* $7.1.2, Function specifiers */  if (friendp && explicitp)    error ("only declarations of constructors can be `explicit'");  if (RIDBIT_SETP (RID_MUTABLE, specbits))    {      if (decl_context == PARM)	{	  error ("non-member `%s' cannot be declared `mutable'", name);	  RIDBIT_RESET (RID_MUTABLE, specbits);	}      else if (friendp || decl_context == TYPENAME)	{	  error ("non-object member `%s' cannot be declared `mutable'", name);	  RIDBIT_RESET (RID_MUTABLE, specbits);	}    }  /* Warn if two storage classes are given. Default to `auto'.  */  if (RIDBIT_ANY_SET (specbits))    {      if (RIDBIT_SETP (RID_STATIC, specbits)) nclasses++;      if (RIDBIT_SETP (RID_EXTERN, specbits)) nclasses++;      if (decl_context == PARM && nclasses > 0)	error ("storage class specifiers invalid in parameter declarations");      if (RIDBIT_SETP (RID_TYPEDEF, specbits))	{	  if (decl_context == PARM)	    error ("typedef declaration invalid in parameter declaration");	  nclasses++;	}      if (RIDBIT_SETP (RID_AUTO, specbits)) nclasses++;      if (RIDBIT_SETP (RID_REGISTER, specbits)) nclasses++;    }  /* Give error if `virtual' is used outside of class declaration.  */  if (virtualp      && (current_class_name == NULL_TREE || decl_context != FIELD))    {      error ("virtual outside class declaration");      virtualp = 0;    }  if (current_class_name == NULL_TREE && RIDBIT_SETP (RID_MUTABLE, specbits))    {      error ("only members can be declared mutable");      RIDBIT_RESET (RID_MUTABLE, specbits);    }  /* Static anonymous unions are dealt with here.  */  if (staticp && decl_context == TYPENAME      && TREE_CODE (declspecs) == TREE_LIST      && ANON_UNION_TYPE_P (TREE_VALUE (declspecs)))    decl_context = FIELD;  /* Give error if `const,' `volatile,' `inline,' `friend,' or `virtual'     is used in a signature member function declaration.  */  if (decl_context == FIELD      && IS_SIGNATURE (current_class_type)      && RIDBIT_NOTSETP (RID_TYPEDEF, specbits))    {      if (type_quals != TYPE_UNQUALIFIED)	{	  error ("type qualifiers specified for signature member function `%s'", name);	  type_quals = TYPE_UNQUALIFIED;	}      if (inlinep)	{	  error ("`inline' specified for signature member function `%s'", name);	  /* Later, we'll make signature member functions inline.  */	  inlinep = 0;	}      if (friendp)	{	  error ("`friend' declaration in signature definition");	  friendp = 0;	}      if (virtualp)	{	  error ("`virtual' specified for signature member function `%s'",		 name);	  /* Later, we'll make signature member functions virtual.  */	  virtualp = 0;	}    }  /* Warn about storage classes that are invalid for certain     kinds of declarations (parameters, typenames, etc.).  */  if (nclasses > 1)    error ("multiple storage classes in declaration of `%s'", name);  else if (decl_context != NORMAL && nclasses > 0)    {      if ((decl_context == PARM || decl_context == CATCHPARM)	  && (RIDBIT_SETP (RID_REGISTER, specbits)	      || RIDBIT_SETP (RID_AUTO, specbits)))	;      else if (RIDBIT_SETP (RID_TYPEDEF, specbits))	;      else if (decl_context == FIELD	       && ! IS_SIGNATURE (current_class_type) 	       /* C++ allows static class elements  */ 	       && RIDBIT_SETP (RID_STATIC, specbits)) 	/* C++ also allows inlines and signed and unsigned elements, 	   but in those cases we don't come in here.  */	;      else	{	  if (decl_context == FIELD)	    {	      tree tmp = NULL_TREE;	      register int op = 0;	      if (declarator)		{		  /* Avoid trying to get an operand off an identifier node.  */ 		  if (TREE_CODE (declarator) == IDENTIFIER_NODE)		    tmp = declarator;		  else		    tmp = TREE_OPERAND (declarator, 0);		  op = IDENTIFIER_OPNAME_P (tmp);		}	      error ("storage class specified for %s `%s'",		     IS_SIGNATURE (current_class_type)		     ? (op			? "signature member operator"			: "signature member function")		     : (op ? "member operator" : "field"),		     op ? operator_name_string (tmp) : name);	    }	  else	    error (((decl_context == PARM || decl_context == CATCHPARM)		    ? "storage class specified for parameter `%s'"		    : "storage class specified for typename"), name);	  RIDBIT_RESET (RID_REGISTER, specbits);	  RIDBIT_RESET (RID_AUTO, specbits);	  RIDBIT_RESET (RID_EXTERN, specbits);	  if (decl_context == FIELD && IS_SIGNATURE (current_class_type))	    {	      RIDBIT_RESET (RID_STATIC, specbits);	      staticp = 0;	    }	}    }  else if (RIDBIT_SETP (RID_EXTERN, specbits) && initialized && !funcdef_flag)    {      if (toplevel_bindings_p ())	{	  /* It's common practice (and completely valid) to have a const	     be initialized and declared extern.  */	  if (!(type_quals & TYPE_QUAL_CONST))	    warning ("`%s' initialized and declared `extern'", name);	}      else	error ("`%s' has both `extern' and initializer", name);    }  else if (RIDBIT_SETP (RID_EXTERN, specbits) && funcdef_flag	   && ! toplevel_bindings_p ())    error ("nested function `%s' declared `extern'", name);  else if (toplevel_bindings_p ())    {      if (RIDBIT_SETP (RID_AUTO, specbits))	error ("top-level declaration of `%s' specifies `auto'", name);    }  if (nclasses > 0 && friendp)    error ("storage class specifiers invalid in friend function declarations");  /* Now figure out the structure of the declarator proper.     Descend through it, creating more complex types, until we reach     the declared identifier (or NULL_TREE, in an absolute declarator).  */  inner_attrs = NULL_TREE;  ignore_attrs = 0;    while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE	 && TREE_CODE (declarator) != TEMPLATE_ID_EXPR)    {      /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]),	 an INDIRECT_REF (for *...),	 a CALL_EXPR (for ...(...)),	 an identifier (for the name being declared)	 or a null pointer (for the place in an absolute declarator	 where the name was omitted).	 For the last two cases, we have just exited the loop.	 For C++ it could also be	 a SCOPE_REF (for class :: ...).  In this case, we have converted	 sensible names to types, and those are the values we use to	 qualify the member name.	 an ADDR_EXPR (for &...),	 a BIT_NOT_EXPR (for destructors)	 At this point, TYPE is the type of elements of an array,	 or for a function to return, or for a pointer to point to.	 After this sequence of ifs, TYPE is the type of the	 array or function or pointer, and DECLARATOR has had its	 outermost layer removed.  */      if (type == error_mark_node)	{	  if (TREE_CODE (declarator) == SCOPE_REF)	    declarator = TREE_OPERAND (declarator, 1);	  else	    declarator = TREE_OPERAND (declarator, 0);	  continue;	}      if (quals != NULL_TREE	  && (declarator == NULL_TREE	      || TREE_CODE (declarator) != SCOPE_REF))	{	  if (ctype == NULL_TREE && TREE_CODE (type) == METHOD_TYPE)	    ctype = TYPE_METHOD_BASETYPE (type);	  if (ctype != NULL_TREE)	    {	      tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);	      ctype = grok_method_quals (ctype, dummy, quals);	      type = TREE_TYPE (dummy);	      quals = NULL_TREE;	    }	}      /* See the comment for the TREE_LIST case, below.  */      if (ignore_attrs)	ignore_attrs = 0;      else if (inner_attrs)	{	  decl_attributes (type, inner_attrs, NULL_TREE);	  inner_attrs = NULL_TREE;	}      switch (TREE_CODE (declarator))	{	case TREE_LIST:	  {	    /* We encode a declarator with embedded attributes using	       a TREE_LIST.  The attributes apply to the declarator	       directly inside them, so we have to skip an iteration	       before applying them to the type.  If the declarator just	       inside is the declarator-id, we apply the attrs to the	       decl itself.  */	    inner_attrs = TREE_PURPOSE (declarator);	    ignore_attrs = 1;	    declarator = TREE_VALUE (declarator);	  }	  break;	case ARRAY_REF:	  {	    register tree itype = NULL_TREE;	    register tree size = TREE_OPERAND (declarator, 1);	    /* The index is a signed object `sizetype' bits wide.  */	    tree index_type = signed_type (sizetype);	    declarator = TREE_OPERAND (declarator, 0);	    /* Check for some types that there cannot be arrays of.  */	    if (TREE_CODE (type) == VOID_TYPE)	      {		cp_error ("declaration of `%D' as array of voids", dname);		type = error_mark_node;	      }	    if (TREE_CODE (type) == FUNCTION_TYPE)	      {		cp_error ("declaration of `%D' as array of functions", dname);		type = error_mark_node;	      }	    /* ARM $8.4.3: Since you can't have a pointer to a reference,	       you can't have arrays of references.  If we allowed them,	       then we'd be saying x[i] is valid for an array x, but	       then you'd have to ask: what does `*(x + i)' mean?  */	    if (TREE_CODE (type) == REFERENCE_TYPE)	      {		if (decl_context == TYPENAME)		  cp_error ("cannot make arrays of references");		else		  cp_error ("declaration of `%D' as array of references",			    dname);		type = error_mark_node;	      }	    if (TREE_CODE (type) == OFFSET_TYPE)	      {		  cp_error ("declaration of `%D' as array of data members",			    dname);		type = error_mark_node;	      }	    if (TREE_CODE (type) == METHOD_TYPE)	      {		cp_error ("declaration of `%D' as array of function members",			  dname);		type = error_mark_node;	      }	    if (size == error_mark_node)	      type = error_mark_node;	    else if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))	      {		/* [dcl.array]		   the constant expressions that specify the bounds of		   the arrays can be omitted only for the first member		   of the sequence.  */		cp_error ("declaration of `%D' as multidimensional array",			  dname);		cp_error ("must have bounds for all dimensions except the first");		type = error_mark_node;	      }	    if (type == error_mark_node)	      continue;	    /* VC++ spells a zero-sized array with [].  */	    if (size == NULL_TREE && decl_context == FIELD && !	staticp		&& ! RIDBIT_SETP (RID_TYPEDEF, specbits))	      size = integer_zero_node;	    if (size)	      {		/* Must suspend_momentary here because the index		   type may need to live until the end of the function.		   For example, it is used in the declaration of a		   variable which requires destructing at the end of		   the function; then build_vec_delete will need this		   value.  */		int yes = suspend_momentary ();		/* Might be a cast. */		if (TREE_CODE (size) == NOP_EXPR		    && TREE_TYPE (size) == TREE_TYPE (TREE_OPERAND (size, 0)))		  size = TREE_OPERAND (size, 0);		/* If this involves a template parameter, it will be a		   constant at instantiation time, but we don't know		   what the value is yet.  Even if no template		   parameters are involved, we may an expression that		   is not a constant; we don't even simplify `1 + 2'		   when processing a template.  */		if (processing_template_decl)		  {		    /* Resolve a qualified reference to an enumerator or		       static const data member of ours.  */		    if (TREE_CODE (size) == SCOPE_REF			&& TREE_OPERAND (size, 0) == current_class_type)		      {			tree t = lookup_field (current_class_type,					       TREE_OPERAND (size, 1), 0, 0);			if (t)			  size = t;		      }		    itype = build_index_type (build_min		      (MINUS_EXPR, sizetype, size, integer_one_node));		    goto dont_grok_size;		  }		if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE		    && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE		    && TREE_CODE (TREE_TYPE (size)) != BOOLEAN_TYPE)		  {		    cp_error ("size of array `%D' has non-integer type",			      dname);		    size = integer_one_node;		  }		if (TREE_READONLY_DECL_P (size))		  size = decl_constant_value (size);		if (pedantic && integer_zerop (size))		  cp_pedwarn ("ANSI C++ forbids zero-size array `%D'", dname);		if (TREE_CONSTANT (size))		  {		    int old_flag_pedantic_errors = flag_pedantic_errors;		    int old_pedantic = pedantic;		    pedantic = flag_pedantic_errors = 1;		    /* Always give overflow errors on array subscripts.  */		    constant_expression_warning (size);		    pedantic = old_pedantic;		    flag_pedantic_errors = old_flag_pedantic_errors;		    if (INT_CST_LT (size, integer_zero_node))		      {			cp_error ("size of array `%D' is negative", dname);			size = integer_one_node;		      }		  }		else		  {		    if (pedantic)		      {			if (dname)			  cp_pedwarn ("ANSI C++ forbids variable-size array `%D'",				      dname);			else			  cp_pedwarn ("ANSI C++ forbids variable-size array");		      }		  }		itype		  = fold (build_binary_op (MINUS_EXPR,					   cp_convert (index_type, size),					   cp_convert (index_type,						       integer_one_node)));		if (! TREE_CONSTANT (itype))		  itype = variable_size (itype);		else if (TREE_OVERFLOW (itype))		  {		    error ("overflow in array dimension");		    TREE_OVERFLOW (itype) = 0;		  }		/* If we're a parm, we need to have a permanent type so                   mangling checks for re-use will work right.  If both the                   element and index types are permanent, the array type                   will be, too.  */		if (decl_context == PARM		    && allocation_temporary_p () && TREE_PERMANENT (type))		  {		    push_obstacks (&permanent_obstack, &permanent_obstack);		    itype = build_index_type (itype);		    pop_obstacks ();		  }		else		  itype = build_index_type (itype);	      dont_grok_size:		resume_momentary (yes);	      }	    type = build_cplus_array_type (type, itype);	    ctype = NULL_TREE;	  }	  break;	case CALL_EXPR:	  {	    tree arg_types;	    int funcdecl_p;	    tree inner_parms = TREE_OPERAND (declarator, 1);	    tree inner_decl = TREE_OPERAND (declarator, 0);	    /* Declaring a function type.	       Make sure we have a valid type for the function to return.  */	    /* We now know that the TYPE_QUALS don't apply to the               decl, but to its return type.  */	    type_quals = TYPE_UNQUALIFIED;	    /* Warn about some types functions can't return.  */	    if (TREE_CODE (type) == FUNCTION_TYPE)	      {		error ("`%s' declared as function returning a function", name);		type = integer_type_node;	      }	    if (TREE_CODE (type) == ARRAY_TYPE)	      {		error ("`%s' declared as function returning an array", name);		type = integer_type_node;	      }	    if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF)	      inner_decl = TREE_OPERAND (inner_decl, 1);	    if (inner_decl && TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR) 	      inner_decl = dname;	    /* Pick up type qualifiers which should be applied to `this'.  */	    quals = TREE_OPERAND (declarator, 2);	    /* Pick up the exception specifications.  */	    raises = TREE_TYPE (declarator);	    /* Say it's a definition only for the CALL_EXPR	       closest to the identifier.  */	    funcdecl_p	      = inner_decl 	      && (TREE_CODE (inner_decl) == IDENTIFIER_NODE		  || TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR 		  || TREE_CODE (inner_decl) == BIT_NOT_EXPR);	    	    if (ctype == NULL_TREE		&& decl_context == FIELD		&& funcdecl_p		&& (friendp == 0 || dname == current_class_name))	      ctype = current_class_type;	    if (ctype && return_type == return_conversion)	      TYPE_HAS_CONVERSION (ctype) = 1;	    if (ctype && constructor_name (ctype) == dname)	      {		/* We are within a class's scope. If our declarator name		   is the same as the class name, and we are defining		   a function, then it is a constructor/destructor, and		   therefore returns a void type.  */		if (flags == DTOR_FLAG)		  {		    /* ANSI C++ June 5 1992 WP 12.4.1.  A destructor may		       not be declared const or volatile.  A destructor		       may not be static.  */		    if (staticp == 2)		      error ("destructor cannot be static member function");		    if (quals)		      {			cp_error ("destructors may not be `%s'",				  IDENTIFIER_POINTER (TREE_VALUE (quals)));			quals = NULL_TREE;		      }		    if (decl_context == FIELD)		      {			if (! member_function_or_else (ctype, current_class_type,						       "destructor for alien class `%s' cannot be a member"))			  return void_type_node;		      }		  }		else            /* It's a constructor.  */		  {		    if (explicitp == 1)		      explicitp = 2;		    /* ANSI C++ June 5 1992 WP 12.1.2.  A constructor may		       not be declared const or volatile.  A constructor may		       not be virtual.  A constructor may not be static.  */		    if (staticp == 2)		      error ("constructor cannot be static member function");		    if (virtualp)		      {			pedwarn ("constructors cannot be declared virtual");			virtualp = 0;		      }		    if (quals)		      {			cp_error ("constructors may not be `%s'",				  IDENTIFIER_POINTER (TREE_VALUE (quals)));			quals = NULL_TREE; 		      }		    {		      RID_BIT_TYPE tmp_bits;		      bcopy ((void*)&specbits, (void*)&tmp_bits, sizeof (RID_BIT_TYPE));		      RIDBIT_RESET (RID_INLINE, tmp_bits);		      RIDBIT_RESET (RID_STATIC, tmp_bits);		      if (RIDBIT_ANY_SET (tmp_bits))			error ("return value type specifier for constructor ignored");		    }		    type = build_pointer_type (ctype);		    if (decl_context == FIELD			&& IS_SIGNATURE (current_class_type))		      {			error ("constructor not allowed in signature");			return void_type_node;		      }			  		    else if (decl_context == FIELD)		      {			if (! member_function_or_else (ctype, current_class_type,						       "constructor for alien class `%s' cannot be member"))			  return void_type_node;			TYPE_HAS_CONSTRUCTOR (ctype) = 1;			if (return_type != return_ctor)			  return NULL_TREE;		      }		  }		if (decl_context == FIELD)		  staticp = 0;	      }	    else if (friendp)	      {		if (initialized)		  error ("can't initialize friend function `%s'", name);		if (virtualp)		  {		    /* Cannot be both friend and virtual.  */		    error ("virtual functions cannot be friends");		    RIDBIT_RESET (RID_FRIEND, specbits);		    friendp = 0;		  }		if (decl_context == NORMAL)		  error ("friend declaration not in class definition");		if (current_function_decl && funcdef_flag)		  cp_error ("can't define friend function `%s' in a local class definition",			    name);	      }	    /* Construct the function type and go to the next	       inner layer of declarator.  */	    declarator = TREE_OPERAND (declarator, 0);	    /* FIXME: This is where default args should be fully	       processed.  */	    arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0);	    if (declarator && flags == DTOR_FLAG)	      {		/* A destructor declared in the body of a class will		   be represented as a BIT_NOT_EXPR.  But, we just		   want the underlying IDENTIFIER.  */		if (TREE_CODE (declarator) == BIT_NOT_EXPR)		  declarator = TREE_OPERAND (declarator, 0);				if (strict_prototype == 0 && arg_types == NULL_TREE)		  arg_types = void_list_node;		else if (arg_types == NULL_TREE			 || arg_types != void_list_node)		  {		    cp_error ("destructors may not have parameters");		    arg_types = void_list_node;		    last_function_parms = NULL_TREE;		  }	      }	    /* ANSI says that `const int foo ();'	       does not make the function foo const.  */	    type = build_function_type (type, arg_types);	    {	      tree t;	      for (t = arg_types; t; t = TREE_CHAIN (t))		if (TREE_PURPOSE (t)		    && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)		  {		    add_defarg_fn (type);		    break;		  }	    }	  }	  break;	case ADDR_EXPR:	case INDIRECT_REF:	  /* Filter out pointers-to-references and references-to-references.	     We can get these if a TYPE_DECL is used.  */	  if (TREE_CODE (type) == REFERENCE_TYPE)	    {	      error ("cannot declare %s to references",		     TREE_CODE (declarator) == ADDR_EXPR		     ? "references" : "pointers");	      declarator = TREE_OPERAND (declarator, 0);	      continue;	    }	  if (TREE_CODE (type) == OFFSET_TYPE	      && (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE		  || TREE_CODE (TREE_TYPE (type)) == REFERENCE_TYPE))	    {	      cp_error ("cannot declare pointer to `%#T' member",			TREE_TYPE (type));	      type = TREE_TYPE (type);	    }	  /* Merge any constancy or volatility into the target type	     for the pointer.  */	  /* We now know that the TYPE_QUALS don't apply to the decl,	     but to the target of the pointer.  */	  type_quals = TYPE_UNQUALIFIED;	  if (IS_SIGNATURE (type))	    {	      if (TREE_CODE (declarator) == ADDR_EXPR)		{		  if (CLASSTYPE_METHOD_VEC (type) == NULL_TREE		      && TYPE_SIZE (type))		    cp_warning ("empty signature `%T' used in signature reference declaration",				type);#if 0		  type = build_signature_reference_type (type);#else		  sorry ("signature reference");		  return NULL_TREE;#endif		}	      else		{		  if (CLASSTYPE_METHOD_VEC (type) == NULL_TREE		      && TYPE_SIZE (type))		    cp_warning ("empty signature `%T' used in signature pointer declaration",				type);		  type = build_signature_pointer_type (type);		}	    }	  else if (TREE_CODE (declarator) == ADDR_EXPR)	    {	      if (TREE_CODE (type) == VOID_TYPE)		error ("invalid type: `void &'");	      else		type = build_reference_type (type);	    }	  else if (TREE_CODE (type) == METHOD_TYPE)	    type = build_ptrmemfunc_type (build_pointer_type (type));	  else	    type = build_pointer_type (type);	  /* Process a list of type modifier keywords (such as	     const or volatile) that were given inside the `*' or `&'.  */	  if (TREE_TYPE (declarator))	    {	      register tree typemodlist;	      int erred = 0;	      constp = 0;	      volatilep = 0;	      restrictp = 0;	      for (typemodlist = TREE_TYPE (declarator); typemodlist;		   typemodlist = TREE_CHAIN (typemodlist))		{		  tree qualifier = TREE_VALUE (typemodlist);		  if (qualifier == ridpointers[(int) RID_CONST])		    constp++;		  else if (qualifier == ridpointers[(int) RID_VOLATILE])		    volatilep++;		  else if (qualifier == ridpointers[(int) RID_RESTRICT])		    restrictp++;		  else if (!erred)		    {		      erred = 1;		      error ("invalid type modifier within pointer declarator");		    }		}	      if (constp > 1)		pedwarn ("duplicate `const'");	      if (volatilep > 1)		pedwarn ("duplicate `volatile'");	      if (restrictp > 1)		pedwarn ("duplicate `restrict'");	      type_quals = ((constp ? TYPE_QUAL_CONST : 0)			    | (restrictp ? TYPE_QUAL_RESTRICT : 0)			    | (volatilep ? TYPE_QUAL_VOLATILE : 0));	      if (TREE_CODE (declarator) == ADDR_EXPR		  && (constp || volatilep))		{		  if (constp)		    pedwarn ("discarding `const' applied to a reference");		  if (volatilep)		    pedwarn ("discarding `volatile' applied to a reference");		  type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);		}	      type = cp_build_qualified_type (type, type_quals);	    }	  declarator = TREE_OPERAND (declarator, 0);	  ctype = NULL_TREE;	  break;	case SCOPE_REF:	  {	    /* We have converted type names to NULL_TREE if the	       name was bogus, or to a _TYPE node, if not.	       The variable CTYPE holds the type we will ultimately	       resolve to.  The code here just needs to build	       up appropriate member types.  */	    tree sname = TREE_OPERAND (declarator, 1);	    tree t;	    /* Destructors can have their visibilities changed as well.  */	    if (TREE_CODE (sname) == BIT_NOT_EXPR)	      sname = TREE_OPERAND (sname, 0);	    if (TREE_COMPLEXITY (declarator) == 0)	      /* This needs to be here, in case we are called		 multiple times.  */ ;	    else if (TREE_COMPLEXITY (declarator) == -1)	      /* Namespace member. */	      pop_decl_namespace ();	    else if (friendp && (TREE_COMPLEXITY (declarator) < 2))	      /* Don't fall out into global scope. Hides real bug? --eichin */ ;	    else if (! IS_AGGR_TYPE_CODE		     (TREE_CODE (TREE_OPERAND (declarator, 0))))	      ;	    else if (TREE_COMPLEXITY (declarator) == current_class_depth)	      {		/* Resolve any TYPENAME_TYPEs from the decl-specifier-seq		   that refer to ctype.  They couldn't be resolved earlier		   because we hadn't pushed into the class yet.		   Example: resolve 'B<T>::type' in		   'B<typename B<T>::type> B<T>::f () { }'.  */		if (current_template_parms		    && uses_template_parms (type)		    && uses_template_parms (current_class_type))		  {		    tree args = current_template_args ();		    type = tsubst (type, args, /*complain=*/1, NULL_TREE);		  }		/* This pop_nested_class corresponds to the                   push_nested_class used to push into class scope for                   parsing the argument list of a function decl, in                   qualified_id.  */		pop_nested_class ();		TREE_COMPLEXITY (declarator) = current_class_depth;	      }	    else	      my_friendly_abort (16);	    if (TREE_OPERAND (declarator, 0) == NULL_TREE)	      {		/* We had a reference to a global decl, or		   perhaps we were given a non-aggregate typedef,		   in which case we cleared this out, and should just		   keep going as though it wasn't there.  */		declarator = sname;		continue;	      }	    ctype = TREE_OPERAND (declarator, 0);	    t = ctype;	    while (t != NULL_TREE && CLASS_TYPE_P (t)) 	      {		if (CLASSTYPE_TEMPLATE_INFO (t) &&		    !CLASSTYPE_TEMPLATE_SPECIALIZATION (t))		  template_count += 1;		t = TYPE_MAIN_DECL (t);		if (DECL_LANG_SPECIFIC (t))		  t = DECL_CLASS_CONTEXT (t);		else		  t = NULL_TREE;	      }	    if (sname == NULL_TREE)	      goto done_scoping;	    if (TREE_CODE (sname) == IDENTIFIER_NODE)	      {		/* This is the `standard' use of the scoping operator:		   basetype :: member .  */		if (ctype == current_class_type)		  {		    /* class A {		         void A::f ();		       };		       Is this ill-formed?  */		    if (pedantic)		      cp_pedwarn ("extra qualification `%T::' on member `%s' ignored",				  ctype, name);		  }		else if (TREE_CODE (type) == FUNCTION_TYPE)		  {		    if (current_class_type == NULL_TREE			|| friendp)		      type = build_cplus_method_type (ctype, TREE_TYPE (type),						      TYPE_ARG_TYPES (type));		    else		      {			cp_error ("cannot declare member function `%T::%s' within `%T'",				  ctype, name, current_class_type);			return void_type_node;		      }		  }		else if (RIDBIT_SETP (RID_TYPEDEF, specbits)			 || TYPE_SIZE (complete_type (ctype)) != NULL_TREE)		  {		    /* Have to move this code elsewhere in this function.		       this code is used for i.e., typedef int A::M; M *pm;		       It is?  How? jason 10/2/94 */		    if (current_class_type)		      {			cp_error ("cannot declare member `%T::%s' within `%T'",				  ctype, name, current_class_type);			return void_type_node;		      }		    type = build_offset_type (ctype, type);		  }		else if (uses_template_parms (ctype))		  {                    if (TREE_CODE (type) == FUNCTION_TYPE)		      type			= build_cplus_method_type (ctype, TREE_TYPE (type),						   TYPE_ARG_TYPES (type));  		  }		else		  {		    cp_error ("structure `%T' not yet defined", ctype);		    return error_mark_node;		  }		declarator = sname;	      }	    else if (TREE_CODE (sname) == SCOPE_REF)	      my_friendly_abort (17);	    else	      {	      done_scoping:		declarator = TREE_OPERAND (declarator, 1);		if (declarator && TREE_CODE (declarator) == CALL_EXPR)		  /* In this case, we will deal with it later.  */		  ;		else		  {		    if (TREE_CODE (type) == FUNCTION_TYPE)		      type = build_cplus_method_type (ctype, TREE_TYPE (type),						      TYPE_ARG_TYPES (type));		    else		      type = build_offset_type (ctype, type);		  }	      }	  }	  break;	case BIT_NOT_EXPR:	  declarator = TREE_OPERAND (declarator, 0);	  break;	case RECORD_TYPE:	case UNION_TYPE:	case ENUMERAL_TYPE:	  declarator = NULL_TREE;	  break;	case ERROR_MARK:	  declarator = NULL_TREE;	  break;	default:	  my_friendly_abort (158);	}    }  /* See the comment for the TREE_LIST case, above.  */  if (inner_attrs)    {      if (! ignore_attrs)	decl_attributes (type, inner_attrs, NULL_TREE);      else if (attrlist)	TREE_VALUE (attrlist) = chainon (inner_attrs, TREE_VALUE (attrlist));      else	attrlist = build_decl_list (NULL_TREE, inner_attrs);    }  /* Now TYPE has the actual type.  */  if (explicitp == 1)    {      error ("only constructors can be declared `explicit'");      explicitp = 0;    }  if (RIDBIT_SETP (RID_MUTABLE, specbits))    {      if (type_quals & TYPE_QUAL_CONST)	{	  error ("const `%s' cannot be declared `mutable'", name);	  RIDBIT_RESET (RID_MUTABLE, specbits);	}      else if (staticp)	{	  error ("static `%s' cannot be declared `mutable'", name);	  RIDBIT_RESET (RID_MUTABLE, specbits);	}    }  if (declarator == NULL_TREE      || TREE_CODE (declarator) == IDENTIFIER_NODE      || (TREE_CODE (declarator) == TEMPLATE_ID_EXPR	  && (TREE_CODE (type) == FUNCTION_TYPE	      || TREE_CODE (type) == METHOD_TYPE)))    /* OK */;  else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)    {      cp_error ("template-id `%D' used as a declarator", declarator);      declarator = dname;    }  else    /* Unexpected declarator format.  */    my_friendly_abort (990210);  /* If this is declaring a typedef name, return a TYPE_DECL.  */  if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME)    {      tree decl;      /* Note that the grammar rejects storage classes	 in typenames, fields or parameters.  */      if (current_lang_name == lang_name_java)	TYPE_FOR_JAVA (type) = 1;      if (decl_context == FIELD)	{	  if (declarator == constructor_name (current_class_type))	    cp_pedwarn ("ANSI C++ forbids nested type `%D' with same name as enclosing class",			declarator);	  decl = build_lang_decl (TYPE_DECL, declarator, type);	  if (IS_SIGNATURE (current_class_type) && opaque_typedef)	    SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1;	}      else	{	  /* Make sure this typedef lives as long as its type,	     since it might be used as a template parameter. */	  if (type != error_mark_node)	    push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));	  decl = build_decl (TYPE_DECL, declarator, type);	  if (type != error_mark_node)	    pop_obstacks ();	}      /* If the user declares "struct {...} foo" then `foo' will have	 an anonymous name.  Fill that name in now.  Nothing can	 refer to it, so nothing needs know about the name change.	 The TYPE_NAME field was filled in by build_struct_xref.  */      if (type != error_mark_node	  && TYPE_NAME (type)	  && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL	  && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))	{	  tree oldname = TYPE_NAME (type);	  tree t;	  /* FIXME: This is bogus; we should not be doing this for	            cv-qualified types.  */	  /* Replace the anonymous name with the real name everywhere.  */	  lookup_tag_reverse (type, declarator);	  for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))	    if (TYPE_NAME (t) == oldname)	      TYPE_NAME (t) = decl;	  if (TYPE_LANG_SPECIFIC (type))	    TYPE_WAS_ANONYMOUS (type) = 1;	  /* If this is a typedef within a template class, the nested	     type is a (non-primary) template.  The name for the	     template needs updating as well.  */	  if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type))	    DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) 	      = TYPE_IDENTIFIER (type);	  /* XXX Temporarily set the scope. 	     When returning, start_decl expects it as NULL_TREE,	     and will then then set it using pushdecl. */	  my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 980404);	  if (current_class_type)	    DECL_CONTEXT (decl) = current_class_type;	  else	    DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);	  DECL_ASSEMBLER_NAME (decl) = DECL_NAME (decl);	  DECL_ASSEMBLER_NAME (decl)	    = get_identifier (build_overload_name (type, 1, 1));	  DECL_CONTEXT (decl) = NULL_TREE;	  /* FIXME remangle member functions; member functions of a	     type with external linkage have external linkage.  */	}      if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE)	{	  cp_error_at ("typedef name may not be class-qualified", decl);	  return NULL_TREE;	}      else if (quals)	{	  if (ctype == NULL_TREE)	    {	      if (TREE_CODE (type) != METHOD_TYPE)		cp_error_at ("invalid type qualifier for non-method type", decl);	      else		ctype = TYPE_METHOD_BASETYPE (type);	    }	  if (ctype != NULL_TREE)	    grok_method_quals (ctype, decl, quals);	}      if (RIDBIT_SETP (RID_SIGNED, specbits)	  || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))	C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;      if (RIDBIT_SETP (RID_MUTABLE, specbits))	error ("non-object member `%s' cannot be declared mutable", name);      bad_specifiers (decl, "type", virtualp, quals != NULL_TREE,		      inlinep, friendp, raises != NULL_TREE);      if (initialized)	error ("typedef declaration includes an initializer");      return decl;    }  /* Detect the case of an array type of unspecified size     which came, as such, direct from a typedef name.     We must copy the type, so that each identifier gets     a distinct type, so that each identifier's size can be     controlled separately by its own initializer.  */  if (type == typedef_type && TREE_CODE (type) == ARRAY_TYPE      && TYPE_DOMAIN (type) == NULL_TREE)    {      type = build_cplus_array_type (TREE_TYPE (type), TYPE_DOMAIN (type));    }  /* If this is a type name (such as, in a cast or sizeof),     compute the type and return it now.  */  if (decl_context == TYPENAME)    {      /* Note that the grammar rejects storage classes	 in typenames, fields or parameters.  */      if (type_quals != TYPE_UNQUALIFIED)	{	  if (IS_SIGNATURE (type))	    error ("type qualifiers specified for signature type");	  type_quals = TYPE_UNQUALIFIED;	}      /* Special case: "friend class foo" looks like a TYPENAME context.  */      if (friendp)	{	  if (type_quals != TYPE_UNQUALIFIED)	    {	      cp_error ("type qualifiers specified for friend class declaration");	      type_quals = TYPE_UNQUALIFIED;	    }	  if (inlinep)	    {	      cp_error ("`inline' specified for friend class declaration");	      inlinep = 0;	    }	  /* Only try to do this stuff if we didn't already give up.  */	  if (type != integer_type_node)	    {	      /* A friendly class?  */	      if (current_class_type)		make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type));	      else		error ("trying to make class `%s' a friend of global scope",		       TYPE_NAME_STRING (type));	      type = void_type_node;	    }	}      else if (quals)	{	  tree dummy = build_decl (TYPE_DECL, declarator, type);	  if (ctype == NULL_TREE)	    {	      my_friendly_assert (TREE_CODE (type) == METHOD_TYPE, 159);	      ctype = TYPE_METHOD_BASETYPE (type);	    }	  grok_method_quals (ctype, dummy, quals);	  type = TREE_TYPE (dummy);	}      return type;    }  else if (declarator == NULL_TREE && decl_context != PARM	   && decl_context != CATCHPARM	   && TREE_CODE (type) != UNION_TYPE	   && ! bitfield)    {      cp_error ("abstract declarator `%T' used as declaration", type);      declarator = make_anon_name ();    }  /* `void' at top level (not within pointer)     is allowed only in typedefs or type names.     We don't complain about parms either, but that is because     a better error message can be made later.  */  if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM)    {      if (! declarator)	error ("unnamed variable or field declared void");      else if (TREE_CODE (declarator) == IDENTIFIER_NODE)	{	  if (IDENTIFIER_OPNAME_P (declarator))	    my_friendly_abort (356);	  else	    error ("variable or field `%s' declared void", name);	}      else	error ("variable or field declared void");      type = integer_type_node;    }  /* Now create the decl, which may be a VAR_DECL, a PARM_DECL     or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */  if (decl_context == PARM || decl_context == CATCHPARM)    {      if (ctype || in_namespace)	error ("cannot use `::' in parameter declaration");      /* A parameter declared as an array of T is really a pointer to T.	 One declared as a function is really a pointer to a function.	 One declared as a member is really a pointer to member.  */      if (TREE_CODE (type) == ARRAY_TYPE)	{	  /* Transfer const-ness of array into that of type pointed to.  */	  type = build_pointer_type (TREE_TYPE (type));	  type_quals = TYPE_UNQUALIFIED;	}      else if (TREE_CODE (type) == FUNCTION_TYPE)	type = build_pointer_type (type);      else if (TREE_CODE (type) == OFFSET_TYPE)	type = build_pointer_type (type);      else if (TREE_CODE (type) == VOID_TYPE && declarator)	{	  error ("declaration of `%s' as void", name);	  return NULL_TREE;	}    }    {    register tree decl;    if (decl_context == PARM)      {	decl = build_decl (PARM_DECL, declarator, type);	bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,			inlinep, friendp, raises != NULL_TREE);	if (current_class_type	    && IS_SIGNATURE (current_class_type))	  {	    if (inlinep)	      error ("parameter of signature member function declared `inline'");	    if (RIDBIT_SETP (RID_AUTO, specbits))	      error ("parameter of signature member function declared `auto'");	    if (RIDBIT_SETP (RID_REGISTER, specbits))	      error ("parameter of signature member function declared `register'");	  }	/* Compute the type actually passed in the parmlist,	   for the case where there is no prototype.	   (For example, shorts and chars are passed as ints.)	   When there is a prototype, this is overridden later.  */	DECL_ARG_TYPE (decl) = type_promotes_to (type);      }    else if (decl_context == FIELD)      {	if (type == error_mark_node)	  {	    /* Happens when declaring arrays of sizes which	       are error_mark_node, for example.  */	    decl = NULL_TREE;	  }	else if (in_namespace && !friendp)	  {	    /* Something like struct S { int N::j; };  */	    cp_error ("invalid use of `::'");	    decl = NULL_TREE;	  }	else if (TREE_CODE (type) == FUNCTION_TYPE)	  {	    int publicp = 0;	    tree function_context;	    /* We catch the others as conflicts with the builtin	       typedefs.  */	    if (friendp && declarator == ridpointers[(int) RID_SIGNED])	      {		cp_error ("function `%D' cannot be declared friend",			  declarator);		friendp = 0;	      }	    if (friendp == 0)	      {		if (ctype == NULL_TREE)		  ctype = current_class_type;		if (ctype == NULL_TREE)		  {		    cp_error ("can't make `%D' into a method -- not in a class",			      declarator);		    return void_type_node;		  }		/* ``A union may [ ... ] not [ have ] virtual functions.''		   ARM 9.5 */		if (virtualp && TREE_CODE (ctype) == UNION_TYPE)		  {		    cp_error ("function `%D' declared virtual inside a union",			      declarator);		    return void_type_node;		  }		if (declarator == ansi_opname[(int) NEW_EXPR]		    || declarator == ansi_opname[(int) VEC_NEW_EXPR]		    || declarator == ansi_opname[(int) DELETE_EXPR]		    || declarator == ansi_opname[(int) VEC_DELETE_EXPR])		  {		    if (virtualp)		      {			cp_error ("`%D' cannot be declared virtual, since it is always static",				  declarator);			virtualp = 0;		      }		  }		else if (staticp < 2)		  type = build_cplus_method_type (ctype, TREE_TYPE (type),						  TYPE_ARG_TYPES (type));	      }	    /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node.  */	    function_context = (ctype != NULL_TREE) ? 	      hack_decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;	    publicp = (! friendp || ! staticp)	      && function_context == NULL_TREE;	    decl = grokfndecl (ctype, type, 			       TREE_CODE (declarator) != TEMPLATE_ID_EXPR			       ? declarator : dname,			       declarator,			       virtualp, flags, quals, raises,			       friendp ? -1 : 0, friendp, publicp, inlinep,			       funcdef_flag, template_count, in_namespace);	    if (decl == NULL_TREE)	      return decl;#if 0	    /* This clobbers the attrs stored in `decl' from `attrlist'.  */	    /* The decl and setting of decl_machine_attr is also turned off.  */	    decl = build_decl_attribute_variant (decl, decl_machine_attr);#endif	    /* [class.conv.ctor]	       A constructor declared without the function-specifier	       explicit that can be called with a single parameter	       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)	      DECL_NONCONVERTING_P (decl) = 1;	    else if (DECL_CONSTRUCTOR_P (decl))	      {		/* The constructor can be called with exactly one		   parameter if there is at least one parameter, and		   any subsequent parameters have default arguments.		   We don't look at the first parameter, which is		   really just the `this' parameter for the new		   object.  */		tree arg_types = 		  TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));		/* Skip the `in_chrg' argument too, if present.  */		if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (decl)))		  arg_types = TREE_CHAIN (arg_types);		/* And the `vlist' argument. */		if (TYPE_USES_PVBASES (DECL_CONTEXT (decl)))		  arg_types = TREE_CHAIN (arg_types);		if (arg_types == void_list_node		    || (arg_types 			&& TREE_CHAIN (arg_types) 			&& TREE_CHAIN (arg_types) != void_list_node			&& !TREE_PURPOSE (TREE_CHAIN (arg_types))))		  DECL_NONCONVERTING_P (decl) = 1;	      }	  }	else if (TREE_CODE (type) == METHOD_TYPE)	  {	    /* We only get here for friend declarations of	       members of other classes.  */	    /* All method decls are public, so tell grokfndecl to set	       TREE_PUBLIC, also.  */	    decl = grokfndecl (ctype, type, declarator, declarator,			       virtualp, flags, quals, raises,			       friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,			       template_count, in_namespace);	    if (decl == NULL_TREE)	      return NULL_TREE;	  }	else if (!staticp && ! processing_template_decl		 && TYPE_SIZE (complete_type (type)) == NULL_TREE		 && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))	  {	    if (declarator)	      cp_error ("field `%D' has incomplete type", declarator);	    else	      cp_error ("name `%T' has incomplete type", type);	    /* If we're instantiating a template, tell them which	       instantiation made the field's type be incomplete.  */	    if (current_class_type		&& TYPE_NAME (current_class_type)		&& IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type))		&& declspecs && TREE_VALUE (declspecs)		&& TREE_TYPE (TREE_VALUE (declspecs)) == type)	      cp_error ("  in instantiation of template `%T'",			current_class_type);	    type = error_mark_node;	    decl = NULL_TREE;	  }	else	  {	    if (friendp)	      {		error ("`%s' is neither function nor method; cannot be declared friend",		       IDENTIFIER_POINTER (declarator));		friendp = 0;	      }	    decl = NULL_TREE;	  }	if (friendp)	  {	    /* Friends are treated specially.  */	    if (ctype == current_class_type)	      warning ("member functions are implicitly friends of their class");	    else	      {		tree t = NULL_TREE;		if (decl && DECL_NAME (decl))		  {		    if (template_class_depth (current_class_type) == 0)		      {			decl 			  = check_explicit_specialization 			  (declarator, decl,			   template_count, 2 * (funcdef_flag != 0) + 4);			if (decl == error_mark_node)			  return error_mark_node;		      }		    t = do_friend (ctype, declarator, decl,				   last_function_parms, attrlist, flags, quals,				   funcdef_flag);		  }		if (t && funcdef_flag)		  return t;				return void_type_node;	      }	  }	/* Structure field.  It may not be a function, except for C++ */	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.  */		    cp_pedwarn ("ANSI C++ forbids initialization of member `%D'",				declarator);		    cp_pedwarn ("making `%D' static", declarator);		    staticp = 1;		  }		if (uses_template_parms (type))		  /* We'll check at instantiation time.  */		  ;		else if (check_static_variable_definition (declarator,							   type))		  /* If we just return the declaration, crashes		     will sometimes occur.  We therefore return		     void_type_node, as if this was a friend		     declaration, to cause callers to completely		     ignore this declaration.  */		  return void_type_node;	      }	    /* 9.2p13 [class.mem] */	    if (declarator == constructor_name (current_class_type)		/* Divergence from the standard:  In extern "C", we		   allow non-static data members here, because C does		   and /usr/include/netinet/in.h uses that.  */		&& (staticp || ! in_system_header))	      cp_pedwarn ("ANSI C++ forbids data member `%D' with same name as enclosing class",			  declarator);	    if (staticp)	      {		/* C++ allows static class members.		   All other work for this is done by grokfield.		   This VAR_DCL is built by build_lang_field_decl.		   All other VAR_DECLs are built by build_decl.  */		decl = build_lang_field_decl (VAR_DECL, declarator, type);		TREE_STATIC (decl) = 1;		/* In class context, 'static' means public access.  */		TREE_PUBLIC (decl) = DECL_EXTERNAL (decl) = 1;	      }	    else	      {		decl = build_lang_field_decl (FIELD_DECL, declarator, type);		if (RIDBIT_SETP (RID_MUTABLE, specbits))		  {		    DECL_MUTABLE_P (decl) = 1;		    RIDBIT_RESET (RID_MUTABLE, specbits);		  }	      }	    bad_specifiers (decl, "field", virtualp, quals != NULL_TREE,			    inlinep, friendp, raises != NULL_TREE);	  }      }    else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)      {	tree original_name;	int publicp = 0;	if (! declarator)	  return NULL_TREE;	if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)	  original_name = dname;	else	  original_name = declarator;	if (RIDBIT_SETP (RID_AUTO, specbits))	  error ("storage class `auto' invalid for function `%s'", name);	else if (RIDBIT_SETP (RID_REGISTER, specbits))	  error ("storage class `register' invalid for function `%s'", name);	/* Function declaration not at top level.	   Storage classes other than `extern' are not allowed	   and `extern' makes no difference.  */	if (! toplevel_bindings_p ()	    && (RIDBIT_SETP (RID_STATIC, specbits)		|| RIDBIT_SETP (RID_INLINE, specbits))	    && pedantic)	  {	    if (RIDBIT_SETP (RID_STATIC, specbits))	      pedwarn ("storage class `static' invalid for function `%s' declared out of global scope", name);	    else	      pedwarn ("storage class `inline' invalid for function `%s' declared out of global scope", name);	  }		if (ctype == NULL_TREE)	  {	    if (virtualp)	      {		error ("virtual non-class function `%s'", name);		virtualp = 0;	      }	  }	else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2)	  type = build_cplus_method_type (ctype, TREE_TYPE (type),					  TYPE_ARG_TYPES (type));	/* Record presence of `static'.  */	publicp = (ctype != NULL_TREE		   || RIDBIT_SETP (RID_EXTERN, specbits)		   || !RIDBIT_SETP (RID_STATIC, specbits));	decl = grokfndecl (ctype, type, original_name, declarator,			   virtualp, flags, quals, raises,			   1, friendp,			   publicp, inlinep, funcdef_flag, 			   template_count, in_namespace);	if (decl == NULL_TREE)	  return NULL_TREE;	if (staticp == 1)	  {	    int illegal_static = 0;	    /* Don't allow a static member function in a class, and forbid	       declaring main to be static.  */	    if (TREE_CODE (type) == METHOD_TYPE)	      {		cp_pedwarn ("cannot declare member function `%D' to have static linkage", decl);		illegal_static = 1;	      }	    else if (current_function_decl)	      {		/* FIXME need arm citation */		error ("cannot declare static function inside another function");		illegal_static = 1;	      }	    if (illegal_static)	      {		staticp = 0;		RIDBIT_RESET (RID_STATIC, specbits);	      }	  }      }    else      {	/* It's a variable.  */	/* An uninitialized decl with `extern' is a reference.  */	decl = grokvardecl (type, declarator, &specbits, 			    initialized, 			    (type_quals & TYPE_QUAL_CONST) != 0, 			    in_namespace);	bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,			inlinep, friendp, raises != NULL_TREE);	if (ctype)	  {	    DECL_CONTEXT (decl) = ctype;	    if (staticp == 1)	      {	        cp_pedwarn ("static member `%D' re-declared as static", decl);	        staticp = 0;		RIDBIT_RESET (RID_STATIC, specbits);	      }	    if (RIDBIT_SETP (RID_REGISTER, specbits) && TREE_STATIC (decl))	      {		cp_error ("static member `%D' declared `register'", decl);		RIDBIT_RESET (RID_REGISTER, specbits);	      }	    if (RIDBIT_SETP (RID_EXTERN, specbits) && pedantic)	      {	        cp_pedwarn ("cannot explicitly declare member `%#D' to have extern linkage",			    decl);		RIDBIT_RESET (RID_EXTERN, specbits);	      }	  }      }    if (RIDBIT_SETP (RID_MUTABLE, specbits))      {	error ("`%s' cannot be declared mutable", name);      }    /* Record `register' declaration for warnings on &       and in case doing stupid register allocation.  */    if (RIDBIT_SETP (RID_REGISTER, specbits))      DECL_REGISTER (decl) = 1;    if (RIDBIT_SETP (RID_EXTERN, specbits))      DECL_THIS_EXTERN (decl) = 1;    if (RIDBIT_SETP (RID_STATIC, specbits))      DECL_THIS_STATIC (decl) = 1;    /* Record constancy and volatility.  */    /* FIXME: Disallow `restrict' pointer-to-member declarations.  */    c_apply_type_quals_to_decl (type_quals, decl);    return decl;  }}