⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cp-decl2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
      && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'      && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr"))    error_with_decl (value, "member `%s' conflicts with virtual function table field name");  /* Stash away type declarations.  */  if (TREE_CODE (value) == TYPE_DECL)    {      DECL_NONLOCAL (value) = 1;      CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;      pushdecl_class_level (value);      return value;    }  if (DECL_IN_AGGR_P (value))    {      error_with_decl (value, "`%s' is already defined in the class %s",		       TYPE_NAME_STRING (DECL_CONTEXT (value)));      return void_type_node;    }  if (flag_cadillac)    cadillac_start_decl (value);  if (asmspec_tree)    asmspec = TREE_STRING_POINTER (asmspec_tree);  if (init != 0)    {      if (TREE_CODE (value) == FUNCTION_DECL)	{	  grok_function_init (value, init);	  init = NULL_TREE;	}      else if (pedantic)	{	  error ("fields cannot have initializers");	  init = NULL_TREE;	}      else	{	  /* We allow initializers to become parameters to base initializers.  */	  if (TREE_CODE (init) == TREE_LIST)	    {	      if (TREE_CHAIN (init) == NULL_TREE)		init = TREE_VALUE (init);	      else		init = digest_init (TREE_TYPE (value), init, 0, 1, 0,				    "field declaration");	    }	  if (TREE_CODE (init) == CONST_DECL)	    init = DECL_INITIAL (init);	  else if (TREE_READONLY_DECL_P (init))	    init = decl_constant_value (init);	  else if (TREE_CODE (init) == CONSTRUCTOR)	    init = digest_init (TREE_TYPE (value), init, 0);	  my_friendly_assert (TREE_PERMANENT (init), 192);	  if (init == error_mark_node)	    /* We must make this look different than `error_mark_node'	       because `decl_const_value' would mis-interpret it	       as only meaning that this VAR_DECL is defined.  */	    init = build1 (NOP_EXPR, TREE_TYPE (value), init);	  else if (! TREE_CONSTANT (init))	    {	      /* We can allow references to things that are effectively		 static, since references are initialized with the address.  */	      if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE		  || (TREE_STATIC (init) == 0		      && (TREE_CODE_CLASS (TREE_CODE (init)) != 'd'			  || DECL_EXTERNAL (init) == 0)))		{		  error ("field initializer is not constant");		  init = error_mark_node;		}	    }	}    }  /* The corresponding pop_obstacks is in finish_decl.  */  push_obstacks_nochange ();  if (TREE_CODE (value) == VAR_DECL)    {      /* We cannot call pushdecl here, because that would	 fill in the value of our TREE_CHAIN.  Instead, we	 modify finish_decl to do the right thing, namely, to	 put this decl out straight away.  */      if (TREE_STATIC (value))	{	  /* current_class_type can be NULL_TREE in case of error.  */	  if (asmspec == 0 && current_class_type)	    {	      tree name;	      char *buf, *buf2;	      buf2 = build_overload_name (current_class_type, 1, 1);	      buf = (char *)alloca (IDENTIFIER_LENGTH (DECL_NAME (value))				    + sizeof (STATIC_NAME_FORMAT)				    + strlen (buf2));	      sprintf (buf, STATIC_NAME_FORMAT, buf2,		       IDENTIFIER_POINTER (DECL_NAME (value)));	      name = get_identifier (buf);	      TREE_PUBLIC (value) = 1;	      DECL_INITIAL (value) = error_mark_node;	      DECL_ASSEMBLER_NAME (value) = name;	    }	  pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics);	  /* Static consts need not be initialized in the class definition.  */	  if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (value)))	    {	      static int explanation = 0;	      error ("initializer invalid for static member with constructor");	      if (explanation++ == 0)		error ("(you really want to initialize it separately)");	      init = 0;	    }	  /* Force the compiler to know when an uninitialized static	     const member is being used.  */	  if (TYPE_READONLY (value) && init == 0)	    TREE_USED (value) = 1;	}      DECL_INITIAL (value) = init;      DECL_IN_AGGR_P (value) = 1;      finish_decl (value, init, asmspec_tree, 1);      pushdecl_class_level (value);      return value;    }  if (TREE_CODE (value) == FIELD_DECL)    {      if (asmspec)	DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec);      if (DECL_INITIAL (value) == error_mark_node)	init = error_mark_node;      finish_decl (value, init, asmspec_tree, 1);      DECL_INITIAL (value) = init;      DECL_IN_AGGR_P (value) = 1;      return value;    }  if (TREE_CODE (value) == FUNCTION_DECL)    {      /* grokdeclarator defers setting this.  */      TREE_PUBLIC (value) = 1;      if (DECL_CHAIN (value) != NULL_TREE)	{	  /* Need a fresh node here so that we don't get circularity	     when we link these together.  */	  value = copy_node (value);	  /* When does this happen?  */	  my_friendly_assert (init == NULL_TREE, 193);	}      finish_decl (value, init, asmspec_tree, 1);      /* Pass friends back this way.  */      if (DECL_FRIEND_P (value))	return void_type_node;      DECL_IN_AGGR_P (value) = 1;      return value;    }  my_friendly_abort (21);  /* NOTREACHED */  return NULL_TREE;}/* Like `grokfield', but for bitfields.   WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.  */treegrokbitfield (declarator, declspecs, width)     tree declarator, declspecs, width;{  register tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL_TREE);  if (! value) return NULL_TREE; /* friends went bad.  */  /* Pass friendly classes back.  */  if (TREE_CODE (value) == VOID_TYPE)    return void_type_node;  if (TREE_CODE (value) == TYPE_DECL)    {      error_with_decl (value, "cannot declare `%s' to be a bitfield type");      return NULL_TREE;    }  if (DECL_IN_AGGR_P (value))    {      error_with_decl (value, "`%s' is already defined in the class %s",		       TYPE_NAME_STRING (DECL_CONTEXT (value)));      return void_type_node;    }  GNU_xref_member (current_class_name, value);  if (TREE_STATIC (value))    {      error_with_decl (value, "static member `%s' cannot be a bitfield");      return NULL_TREE;    }  finish_decl (value, NULL_TREE, NULL_TREE, 0);  if (width != error_mark_node)    {      /* detect invalid field size.  */      if (TREE_CODE (width) == CONST_DECL)	width = DECL_INITIAL (width);      else if (TREE_READONLY_DECL_P (width))	width = decl_constant_value (width);      if (TREE_CODE (width) != INTEGER_CST)	{	  error_with_decl (value, "structure field `%s' width not an integer constant");	  DECL_INITIAL (value) = NULL_TREE;	}      else	{	  DECL_INITIAL (value) = width;	  DECL_BIT_FIELD (value) = 1;	}    }  DECL_IN_AGGR_P (value) = 1;  return value;}/* Like GROKFIELD, except that the declarator has been   buried in DECLSPECS.  Find the declarator, and   return something that looks like it came from   GROKFIELD.  */treegroktypefield (declspecs, parmlist)     tree declspecs;     tree parmlist;{  tree spec = declspecs;  tree prev = NULL_TREE;  tree type_id = NULL_TREE;  tree quals = NULL_TREE;  tree lengths = NULL_TREE;  tree decl = NULL_TREE;  while (spec)    {      register tree id = TREE_VALUE (spec);      if (TREE_CODE (spec) != TREE_LIST)	/* Certain parse errors slip through.  For example,	   `int class ();' is not caught by the parser. Try	   weakly to recover here.  */	return NULL_TREE;      if (TREE_CODE (id) == TYPE_DECL	  || (TREE_CODE (id) == IDENTIFIER_NODE && TREE_TYPE (id)))	{	  /* We have a constructor/destructor or	     conversion operator.  Use it.  */	  if (prev)	    TREE_CHAIN (prev) = TREE_CHAIN (spec);	  else	    declspecs = TREE_CHAIN (spec);	  type_id = id;	  goto found;	}      prev = spec;      spec = TREE_CHAIN (spec);    }  /* Nope, we have a conversion operator to a scalar type or something     else, that includes things like constructor declarations for     templates.  */  spec = declspecs;  while (spec)    {      tree id = TREE_VALUE (spec);      if (TREE_CODE (id) == IDENTIFIER_NODE)	{	  if (id == ridpointers[(int)RID_INT]	      || id == ridpointers[(int)RID_DOUBLE]	      || id == ridpointers[(int)RID_FLOAT]	      || id == ridpointers[(int)RID_WCHAR])	    {	      if (type_id)		error ("extra `%s' ignored",		       IDENTIFIER_POINTER (id));	      else		type_id = id;	    }	  else if (id == ridpointers[(int)RID_LONG]		   || id == ridpointers[(int)RID_SHORT]		   || id == ridpointers[(int)RID_CHAR])	    {	      lengths = tree_cons (NULL_TREE, id, lengths);	    }	  else if (id == ridpointers[(int)RID_VOID])	    {	      if (type_id)		error ("spurious `void' type ignored");	      else		error ("conversion to `void' type invalid");	    }	  else if (id == ridpointers[(int)RID_AUTO]		   || id == ridpointers[(int)RID_REGISTER]		   || id == ridpointers[(int)RID_TYPEDEF]		   || id == ridpointers[(int)RID_CONST]		   || id == ridpointers[(int)RID_VOLATILE])	    {	      error ("type specifier `%s' used invalidly",		     IDENTIFIER_POINTER (id));	    }	  else if (id == ridpointers[(int)RID_FRIEND]		   || id == ridpointers[(int)RID_VIRTUAL]		   || id == ridpointers[(int)RID_INLINE]		   || id == ridpointers[(int)RID_UNSIGNED]		   || id == ridpointers[(int)RID_SIGNED]		   || id == ridpointers[(int)RID_STATIC]		   || id == ridpointers[(int)RID_EXTERN])	    {	      quals = tree_cons (NULL_TREE, id, quals);	    }	  else	    {	      /* Happens when we have a global typedef		 and a class-local member function with		 the same name.  */	      type_id = id;	      goto found;	    }	}      else if (TREE_CODE (id) == RECORD_TYPE)	{	  type_id = TYPE_NAME (id);	  if (TREE_CODE (type_id) == TYPE_DECL)	    type_id = DECL_NAME (type_id);	  if (type_id == NULL_TREE)	    error ("identifier for aggregate type conversion omitted");	}      else if (TREE_CODE_CLASS (TREE_CODE (id)) == 't')	{	  error ("`operator' missing on conversion operator or tag missing from type");	}      else	my_friendly_assert (0, 194);      spec = TREE_CHAIN (spec);    }  if (type_id)    {      declspecs = chainon (lengths, quals);    }  else if (lengths)    {      if (TREE_CHAIN (lengths))	error ("multiple length specifiers");      type_id = ridpointers[(int)RID_INT];      declspecs = chainon (lengths, quals);    }  else if (quals)    {      error ("no type given, defaulting to `operator int ...'");      type_id = ridpointers[(int)RID_INT];      declspecs = quals;    }  else return NULL_TREE; found:  decl = grokdeclarator (build_parse_node (CALL_EXPR, type_id, parmlist, NULL_TREE),			 declspecs, FIELD, 0, NULL_TREE);  if (decl == NULL_TREE)    return NULL_TREE;  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CHAIN (decl) != NULL_TREE)    {      /* Need a fresh node here so that we don't get circularity	 when we link these together.  */      decl = copy_node (decl);    }  if (decl == void_type_node      || (TREE_CODE (decl) == FUNCTION_DECL	  && TREE_CODE (TREE_TYPE (decl)) != METHOD_TYPE))    /* bunch of friends.  */    return decl;  if (DECL_IN_AGGR_P (decl))    {      error_with_decl (decl, "`%s' already defined in the class ");      return void_type_node;    }  finish_decl (decl, NULL_TREE, NULL_TREE, 0);  /* If this declaration is common to another declaration     complain about such redundancy, and return NULL_TREE     so that we don't build a circular list.  */  if (DECL_CHAIN (decl))    {      error_with_decl (decl, "function `%s' declared twice in class %s",		       TYPE_NAME_STRING (DECL_CONTEXT (decl)));      return NULL_TREE;    }  DECL_IN_AGGR_P (decl) = 1;  return decl;}/* The precedence rules of this grammar (or any other deterministic LALR   grammar, for that matter), place the CALL_EXPR somewhere where we   may not want it.  The solution is to grab the first CALL_EXPR we see,   pretend that that is the one that belongs to the parameter list of   the type conversion function, and leave everything else alone.   We pull it out in place.   CALL_REQUIRED is non-zero if we should complain if a CALL_EXPR   does not appear in DECL.  */treegrokoptypename (decl, call_required)     tree decl;     int call_required;{  tree tmp, last;  my_friendly_assert (TREE_CODE (decl) == TYPE_EXPR, 195);  tmp = TREE_OPERAND (decl, 0);  last = NULL_TREE;  while (tmp)    {      switch (TREE_CODE (tmp))	{	case CALL_EXPR:	  {	    tree parms = TREE_OPERAND (tmp, 1);	    if (last)	      TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0);	    else	      TREE_OPERAND (decl, 0) = TREE_OPERAND (tmp, 0);	    if (parms

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -