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

📄 decl2.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
   C++:   If class A defines that certain functions in class B are friends, then   the way I have set things up, it is B who is interested in permission   granted by A.  However, it is in A's context that these declarations   are parsed.  By returning a void_type_node, class A does not attempt   to incorporate the declarations of the friends within its structure.   DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING   CHANGES TO CODE IN `start_method'.  */treegrokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)     tree declarator, declspecs, raises, init, asmspec_tree, attrlist;{  register tree value;  char *asmspec = 0;  int flags = LOOKUP_ONLYCONVERTING;  /* Convert () initializers to = initializers.  */  if (init == NULL_TREE && declarator != NULL_TREE      && TREE_CODE (declarator) == CALL_EXPR      && TREE_OPERAND (declarator, 0)      && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE	  || TREE_CODE (TREE_OPERAND (declarator, 0)) == SCOPE_REF)      && parmlist_is_exprlist (TREE_OPERAND (declarator, 1)))    {      init = TREE_OPERAND (declarator, 1);      declarator = TREE_OPERAND (declarator, 0);      flags = 0;    }  if (init      && TREE_CODE (init) == TREE_LIST      && TREE_VALUE (init) == error_mark_node      && TREE_CHAIN (init) == NULL_TREE)	init = NULL_TREE;  value = grokdeclarator (declarator, declspecs, FIELD, init != 0,			  raises, attrlist);  if (! value)    return value; /* friend or constructor went bad.  */  /* Pass friendly classes back.  */  if (TREE_CODE (value) == VOID_TYPE)    return void_type_node;  if (DECL_NAME (value) != NULL_TREE      && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'      && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr"))    cp_error ("member `%D' conflicts with virtual function table field name", value);  /* Stash away type declarations.  */  if (TREE_CODE (value) == TYPE_DECL)    {      DECL_NONLOCAL (value) = 1;      DECL_CONTEXT (value) = current_class_type;      DECL_CLASS_CONTEXT (value) = current_class_type;      CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;      /* If we declare a typedef name for something that has no name,	 the typedef name is used for linkage.  See 7.1.3 p4 94/0158. */      if (TYPE_NAME (TREE_TYPE (value))	  && TREE_CODE (TYPE_NAME (TREE_TYPE (value))) == TYPE_DECL	  && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TREE_TYPE (value))))	{	  TYPE_NAME (TREE_TYPE (value)) = value;	  TYPE_STUB_DECL (TREE_TYPE (value)) = value;	}      pushdecl_class_level (value);      return value;    }  if (IS_SIGNATURE (current_class_type)      && TREE_CODE (value) != FUNCTION_DECL)    {      error ("field declaration not allowed in signature");      return void_type_node;    }  if (DECL_IN_AGGR_P (value))    {      cp_error ("`%D' is already defined in the class %T", value,		  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)    {      if (IS_SIGNATURE (current_class_type)	  && TREE_CODE (value) == FUNCTION_DECL)	{	  error ("function declarations cannot have initializers in signature");	  init = NULL_TREE;	}      else if (TREE_CODE (value) == FUNCTION_DECL)	{	  grok_function_init (value, init);	  init = NULL_TREE;	}      else if (pedantic && TREE_CODE (value) != VAR_DECL)	/* Already complained in grokdeclarator.  */	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, (tree *)0);	    }	  	  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, (tree *)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 cp_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 cp_finish_decl to do the right thing, namely, to	 put this decl out straight away.  */      if (TREE_PUBLIC (value))	{	  /* current_class_type can be NULL_TREE in case of error.  */	  if (asmspec == 0 && current_class_type)	    {	      TREE_PUBLIC (value) = 1;	      DECL_INITIAL (value) = error_mark_node;	      DECL_ASSEMBLER_NAME (value)		= build_static_name (current_class_type, DECL_NAME (value));	    }	  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;      cp_finish_decl (value, init, asmspec_tree, 1, flags);      pushdecl_class_level (value);      return value;    }  if (TREE_CODE (value) == FIELD_DECL)    {      if (asmspec)	{	  /* This must override the asm specifier which was placed	     by grokclassfn.  Lay this out fresh.  */	  DECL_RTL (value) = NULL_RTX;	  DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec);	}      if (DECL_INITIAL (value) == error_mark_node)	init = error_mark_node;      cp_finish_decl (value, init, asmspec_tree, 1, flags);      DECL_INITIAL (value) = init;      DECL_IN_AGGR_P (value) = 1;      return value;    }  if (TREE_CODE (value) == FUNCTION_DECL)    {      check_default_args (value);      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);	}      if (asmspec)	{	  /* This must override the asm specifier which was placed	     by grokclassfn.  Lay this out fresh.  */	  DECL_RTL (value) = NULL_RTX;	  DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec);	}      cp_finish_decl (value, init, asmspec_tree, 1, flags);      /* Pass friends back this way.  */      if (DECL_FRIEND_P (value))	return void_type_node;#if 0 /* Just because a fn is declared doesn't mean we'll try to define it.  */      if (current_function_decl && ! IS_SIGNATURE (current_class_type))	cp_error ("method `%#D' of local class must be defined in class body",		  value);#endif      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, 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)    {      cp_error ("cannot declare `%D' to be a bitfield type", value);      return NULL_TREE;    }  if (IS_SIGNATURE (current_class_type))    {      error ("field declaration not allowed in signature");      return void_type_node;    }  if (DECL_IN_AGGR_P (value))    {      cp_error ("`%D' is already defined in the class %T", value,		  DECL_CONTEXT (value));      return void_type_node;    }  GNU_xref_member (current_class_name, value);  if (TREE_STATIC (value))    {      cp_error ("static member `%D' cannot be a bitfield", value);      return NULL_TREE;    }  cp_finish_decl (value, NULL_TREE, NULL_TREE, 0, 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)	{	  cp_error ("structure field `%D' width not an integer constant",		      value);	  DECL_INITIAL (value) = NULL_TREE;	}      else	{	  constant_expression_warning (width);	  DECL_INITIAL (value) = width;	  DECL_BIT_FIELD (value) = 1;	}    }  DECL_IN_AGGR_P (value) = 1;  return value;}#if 0/* 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_abort (194);      spec = TREE_CHAIN (spec);    }  if (type_id)    declspecs = chainon (lengths, quals);  else if (lengths)    {

⌨️ 快捷键说明

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