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

📄 c-decl.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	{	  /* If you declare a built-in function name as static, the	     built-in definition is overridden,	     but optionally warn this was a bad choice of name.  */	  if (!TREE_PUBLIC (newdecl))	    {	      if (warn_shadow)		warning_with_decl (newdecl, "shadowing built-in function `%s'");	    }	  /* Likewise, if the built-in is not ansi, then programs can	     override it even globally without an error.  */	  else if (DECL_BUILT_IN_NONANSI (olddecl))	    warning_with_decl (newdecl,			       "built-in function `%s' declared as non-function");	  else	    error_with_decl (newdecl,			     "built-in function `%s' declared as non-function");	}      else if (TREE_CODE (olddecl) == FUNCTION_DECL	       && DECL_BUILT_IN_NONANSI (olddecl))	{	  /* If overriding decl is static,	     optionally warn this was a bad choice of name.  */	  if (!TREE_PUBLIC (newdecl))	    {	      if (warn_shadow)		warning_with_decl (newdecl, "shadowing library function `%s'");	    }	  /* Otherwise, always warn.  */	  else	    warning_with_decl (newdecl,			       "library function `%s' declared as non-function");	}      else	{	  error_with_decl (newdecl, "`%s' redeclared as different kind of symbol");	  error_with_decl (olddecl, "previous declaration of `%s'");	}      return 0;    }  /* For real parm decl following a forward decl,     return 1 so old decl will be reused.  */  if (types_match && TREE_CODE (newdecl) == PARM_DECL      && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))    return 1;  /* The new declaration is the same kind of object as the old one.     The declarations may partially match.  Print warnings if they don't     match enough.  Ultimately, copy most of the information from the new     decl to the old one, and keep using the old one.  */  if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL      && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (newdecl)) == olddecl      && DECL_INITIAL (olddecl) == 0)    /* If -traditional, avoid error for redeclaring fcn       after implicit decl.  */    ;  else if (TREE_CODE (olddecl) == FUNCTION_DECL	   && DECL_BUILT_IN (olddecl))    {      /* A function declaration for a built-in function.  */      if (!TREE_PUBLIC (newdecl))	{	  /* If you declare a built-in function name as static, the	     built-in definition is overridden,	     but optionally warn this was a bad choice of name.  */	  if (warn_shadow)	    warning_with_decl (newdecl, "shadowing built-in function `%s'");	  /* Discard the old built-in function.  */	  return 0;	}      else if (!types_match)	{          /* Accept the return type of the new declaration if same modes.  */	  tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));	  tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));          if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))            {	      /* Function types may be shared, so we can't just modify		 the return type of olddecl's function type.  */	      tree newtype		= build_function_type (newreturntype,				       TYPE_ARG_TYPES (TREE_TYPE (olddecl)));	                    types_match = comptypes (TREE_TYPE (newdecl), newtype);	      if (types_match)		TREE_TYPE (olddecl) = newtype;	    }	}      if (!types_match)	{	  /* If types don't match for a built-in, throw away the built-in.  */	  warning_with_decl (newdecl, "conflicting types for built-in function `%s'");	  return 0;	}    }  else if (TREE_CODE (olddecl) == FUNCTION_DECL	   && DECL_SOURCE_LINE (olddecl) == 0)    {      /* A function declaration for a predeclared function	 that isn't actually built in.  */      if (!TREE_PUBLIC (newdecl))	{	  /* If you declare it as static, the	     default definition is overridden.  */	  return 0;	}      else if (!types_match)	{	  /* If the types don't match, preserve volatility indication.	     Later on, we will discard everything else about the	     default declaration.  */	  TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);	}    }  /* Permit char *foo () to match void *foo (...) if not pedantic,     if one of them came from a system header file.  */  else if (!types_match	   && TREE_CODE (olddecl) == FUNCTION_DECL	   && TREE_CODE (newdecl) == FUNCTION_DECL	   && TREE_CODE (TREE_TYPE (oldtype)) == POINTER_TYPE	   && TREE_CODE (TREE_TYPE (newtype)) == POINTER_TYPE	   && (DECL_IN_SYSTEM_HEADER (olddecl)	       || DECL_IN_SYSTEM_HEADER (newdecl))	   && ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (newtype))) == void_type_node		&& TYPE_ARG_TYPES (oldtype) == 0		&& self_promoting_args_p (TYPE_ARG_TYPES (newtype))		&& TREE_TYPE (TREE_TYPE (oldtype)) == char_type_node)	       ||	       (TREE_TYPE (TREE_TYPE (newtype)) == char_type_node		&& TYPE_ARG_TYPES (newtype) == 0		&& self_promoting_args_p (TYPE_ARG_TYPES (oldtype))		&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)))    {      if (pedantic)	pedwarn_with_decl (newdecl, "conflicting types for `%s'");      /* Make sure we keep void * as ret type, not char *.  */      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)	TREE_TYPE (newdecl) = newtype = oldtype;    }  else if (!types_match	   /* Permit char *foo (int, ...); followed by char *foo ();	      if not pedantic.  */	   && ! (TREE_CODE (olddecl) == FUNCTION_DECL		 && ! pedantic		 /* Return types must still match.  */		 && comptypes (TREE_TYPE (oldtype),			       TREE_TYPE (newtype))		 && TYPE_ARG_TYPES (newtype) == 0))    {      error_with_decl (newdecl, "conflicting types for `%s'");      /* Check for function type mismatch	 involving an empty arglist vs a nonempty one.  */      if (TREE_CODE (olddecl) == FUNCTION_DECL	  && comptypes (TREE_TYPE (oldtype),			TREE_TYPE (newtype))	  && ((TYPE_ARG_TYPES (oldtype) == 0	       && DECL_INITIAL (olddecl) == 0)	      ||	      (TYPE_ARG_TYPES (newtype) == 0	       && DECL_INITIAL (newdecl) == 0)))	{	  /* Classify the problem further.  */	  register tree t = TYPE_ARG_TYPES (oldtype);	  if (t == 0)	    t = TYPE_ARG_TYPES (newtype);	  for (; t; t = TREE_CHAIN (t))	    {	      register tree type = TREE_VALUE (t);	      if (TREE_CHAIN (t) == 0		  && TYPE_MAIN_VARIANT (type) != void_type_node)		{		  error ("A parameter list with an ellipsis can't match");		  error ("an empty parameter name list declaration.");		  break;		}	      if (TYPE_MAIN_VARIANT (type) == float_type_node		  || C_PROMOTING_INTEGER_TYPE_P (type))		{		  error ("An argument type that has a default promotion");		  error ("can't match an empty parameter name list declaration.");		  break;		}	    }	}      error_with_decl (olddecl, "previous declaration of `%s'");    }  else    {      char *errmsg = redeclaration_error_message (newdecl, olddecl);      if (errmsg)	{	  error_with_decl (newdecl, errmsg);	  error_with_decl (olddecl,			   ((DECL_INITIAL (olddecl)			     && current_binding_level == global_binding_level)			    ? "`%s' previously defined here"			    : "`%s' previously declared here"));	}      else if (TREE_CODE (olddecl) == FUNCTION_DECL	       && DECL_INITIAL (olddecl) != 0	       && TYPE_ARG_TYPES (oldtype) == 0	       && TYPE_ARG_TYPES (newtype) != 0)	{	  register tree type, parm;	  register int nargs;	  /* Prototype decl follows defn w/o prototype.  */	  for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype),	       type = TYPE_ARG_TYPES (newtype),	       nargs = 1;	       (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) != void_type_node		|| TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node);	       parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++)	    {	      if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node		  || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)		{		  errmsg = "prototype for `%s' follows and number of arguments";		  break;		}	      /* Type for passing arg must be consistent		 with that declared for the arg.  */	      if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type))		  /* If -traditional, allow `unsigned int' instead of `int'		     in the prototype.  */		  && (! (flag_traditional			 && TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node			 && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node)))		{		  errmsg = "prototype for `%s' follows and argument %d";		  break;		}	    }	  if (errmsg)	    {	      error_with_decl (newdecl, errmsg, nargs);	      error_with_decl (olddecl,			       "doesn't match non-prototype definition here");	    }	  else	    {	      warning_with_decl (newdecl, "prototype for `%s' follows");	      warning_with_decl (olddecl, "non-prototype definition here");	    }	}      /* Warn about mismatches in various flags.  */      else	{	  /* Warn if function is now inline	     but was previously declared not inline and has been called.  */	  if (TREE_CODE (olddecl) == FUNCTION_DECL	      && ! DECL_INLINE (olddecl) && DECL_INLINE (newdecl)	      && TREE_USED (olddecl))	    warning_with_decl (newdecl,			       "`%s' declared inline after being called");	  if (TREE_CODE (olddecl) == FUNCTION_DECL	      && ! DECL_INLINE (olddecl) && DECL_INLINE (newdecl)	      && DECL_INITIAL (olddecl) != 0)	    warning_with_decl (newdecl,			       "`%s' declared inline after its definition");	  /* It is nice to warn when a function is declared	     global first and then static.  */	  if (TREE_CODE (olddecl) == FUNCTION_DECL	      && TREE_PUBLIC (olddecl)	      && !TREE_PUBLIC (newdecl))	    warning_with_decl (newdecl, "static declaration for `%s' follows non-static");	  /* These bits are logically part of the type, for variables.	     But not for functions	     (where qualifiers are not valid ANSI anyway).  */	  if (pedantic && TREE_CODE (olddecl) != FUNCTION_DECL	      && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)		  || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))	    pedwarn_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl");	}    }  /* Optionally warn about more than one declaration for the same name.  */  if (warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0      /* Dont warn about a function declaration	 followed by a definition.  */      && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0	   && DECL_INITIAL (olddecl) == 0))    {      warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope");      warning_with_decl (olddecl, "previous declaration of `%s'");    }  /* Copy all the DECL_... slots specified in the new decl     except for any that we copy here from the old type.     Past this point, we don't change OLDTYPE and NEWTYPE     even if we change the types of NEWDECL and OLDDECL.  */  if (types_match)    {      /* Merge the data types specified in the two decls.  */      if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))	TREE_TYPE (newdecl)	  = TREE_TYPE (olddecl)	    = common_type (newtype, oldtype);      /* Lay the type out, unless already done.  */      if (oldtype != TREE_TYPE (newdecl))	{	  if (TREE_TYPE (newdecl) != error_mark_node)	    layout_type (TREE_TYPE (newdecl));	  if (TREE_CODE (newdecl) != FUNCTION_DECL	      && TREE_CODE (newdecl) != TYPE_DECL	      && TREE_CODE (newdecl) != CONST_DECL)	    layout_decl (newdecl, 0);	}      else	{	  /* Since the type is OLDDECL's, make OLDDECL's size go with.  */	  DECL_SIZE (newdecl) = DECL_SIZE (olddecl);	  if (TREE_CODE (olddecl) != FUNCTION_DECL)	    if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))	      DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);	}      /* Keep the old rtl since we can safely use it.  */      DECL_RTL (newdecl) = DECL_RTL (olddecl);      /* Merge the type qualifiers.  */      if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)	  && !TREE_THIS_VOLATILE (newdecl))	TREE_THIS_VOLATILE (olddecl) = 0;      if (TREE_READONLY (newdecl))	TREE_READONLY (olddecl) = 1;      if (TREE_THIS_VOLATILE (newdecl))	{	  TREE_THIS_VOLATILE (olddecl) = 1;	  if (TREE_CODE (newdecl) == VAR_DECL)	    make_var_volatile (newdecl);	}      /* Keep source location of definition rather than declaration.  */      if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)	{	  DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);	  DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);	}      /* Merge the unused-warning information.  */      if (DECL_IN_SYSTEM_HEADER (olddecl))	DECL_IN_SYSTEM_HEADER (newdecl) = 1;      else if (DECL_IN_SYSTEM_HEADER (newdecl))	DECL_IN_SYSTEM_HEADER (olddecl) = 1;      /* Merge the initialization information.  */      if (DECL_INITIAL (newdecl) == 0)	DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);    }  /* If cannot merge, then use the new type and qualifiers,     and don't preserve the old rtl.  */  else    {      TREE_TYPE (olddecl) = TREE_TYPE (newdecl);      TREE_READONLY (olddecl) = TREE_READONLY (newdecl);      TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);      TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);    }  /* Merge the storage class information.  */  /* For functions, static overrides non-static.  */  if (TREE_CODE (newdecl) == FUNCTION_DECL)    {      TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);      /* This is since we don't automatically	 copy the attributes of NEWDECL into OLDDECL.  */      TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);      /* If this clears `static', clear it in the identifier too.  */      if (! TREE_PUBLIC (olddecl))	TREE_PUBLIC (DECL_NAME (olddecl)) = 0;    }  if (DECL_EXTERNAL (newdecl))    {      TREE_STATIC (newdecl) = TREE_STATIC (olddecl);      DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);      /* An extern decl does not override previous storage class.  */      TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);    }  else    {      TREE_STATIC (olddecl) = TREE_STATIC (newdecl);      TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);    }  /* If either decl says `inline', this fn is inline,     unless its definition was passed already.  */  if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)    DECL_INLINE (olddecl) = 1;  DECL_INLINE (newdecl) = DECL_INLINE (olddecl);  /* Get rid of any built-in function if new arg types don't match it     or if we have a function definition.  */  if (TREE_CODE (newdecl) == FUNCTION_DECL      && DECL_BUILT_IN (olddecl)      && (!types_match || new_is_definition))    {      TREE_TYPE (olddecl) = TREE_TYPE (newdecl);      DECL_BUILT_IN (olddecl) = 0;    }

⌨️ 快捷键说明

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