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

📄 c-decl.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		  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    {      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 (newdecl) == TYPE_DECL               && (DECL_IN_SYSTEM_HEADER (olddecl)                    || DECL_IN_SYSTEM_HEADER (newdecl)))	{	  warning_with_decl (newdecl, "redefinition of `%s'");	  warning_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	       && TYPE_ACTUAL_ARG_TYPES (oldtype) != 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");	  /* If pedantic, warn when static declaration follows a non-static	     declaration.  Otherwise, do so only for functions.  */	  if ((pedantic || TREE_CODE (olddecl) == FUNCTION_DECL)	      && TREE_PUBLIC (olddecl)	      && !TREE_PUBLIC (newdecl))	    warning_with_decl (newdecl, "static declaration for `%s' follows non-static");	  /* Warn when const declaration follows a non-const	     declaration, but not for functions.  */	  if (TREE_CODE (olddecl) != FUNCTION_DECL	      && !TREE_READONLY (olddecl)	      && TREE_READONLY (newdecl))	    warning_with_decl (newdecl, "const declaration for `%s' follows non-const");	  /* These bits are logically part of the type, for variables.	     But not for functions	     (where qualifiers are not valid ANSI anyway).  */	  else 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 (errmsg == 0 && warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0      /* Don't warn about a function declaration	 followed by a definition.  */      && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0	   && DECL_INITIAL (olddecl) == 0)      /* Don't warn about extern decl followed by (tentative) definition.  */      && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))    {      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)    {      /* When copying info to olddecl, we store into write_olddecl	 instead.  This allows us to avoid modifying olddecl when	 different_binding_level is true.  */      tree write_olddecl = different_binding_level ? newdecl : olddecl;      /* Make sure we put the new type in the same obstack as the old ones.	 If the old types are not both in the same obstack, use the permanent	 one.  */      if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))	push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));      else	{	  push_obstacks_nochange ();	  end_temporary_allocation ();	}		             /* Merge the data types specified in the two decls.  */      if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))	{	  if (different_binding_level)	    TREE_TYPE (newdecl)	      = build_type_attribute_variant		(newtype,		 merge_attributes (TYPE_ATTRIBUTES (newtype),				   TYPE_ATTRIBUTES (oldtype)));	  else	    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 (write_olddecl) = 0;      if (TREE_READONLY (newdecl))	TREE_READONLY (write_olddecl) = 1;      if (TREE_THIS_VOLATILE (newdecl))	{	  TREE_THIS_VOLATILE (write_olddecl) = 1;	  if (TREE_CODE (newdecl) == VAR_DECL)	    make_var_volatile (newdecl);	}      /* Keep source location of definition rather than declaration.  */      /* When called with different_binding_level set, keep the old	 information so that meaningful diagnostics can be given.  */      if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0	  && ! different_binding_level)	{	  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 (write_olddecl) = 1;      /* Merge the initialization information.  */      /* When called with different_binding_level set, don't copy over	 DECL_INITIAL, so that we don't accidentally change function	 declarations into function definitions.  */      if (DECL_INITIAL (newdecl) == 0 && ! different_binding_level)	DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);      /* Merge the section attribute.         We want to issue an error if the sections conflict but that must be	 done later in decl_attributes since we are called before attributes	 are assigned.  */      if (DECL_SECTION_NAME (newdecl) == NULL_TREE)	DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);      if (TREE_CODE (newdecl) == FUNCTION_DECL)	{	  DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);	  DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);	}      pop_obstacks ();    }  /* If cannot merge, then use the new type and qualifiers,     and don't preserve the old rtl.  */  else if (! different_binding_level)    {      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.  */  DECL_WEAK (newdecl) |= DECL_WEAK (olddecl);	    /* 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.  */      /* No need to worry about different_binding_level here because	 then TREE_PUBLIC (newdecl) was true.  */      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);      if (! DECL_EXTERNAL (newdecl))	DECL_CONTEXT (newdecl) = DECL_CONTEXT (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);  if (TREE_CODE (newdecl) == FUNCTION_DECL)    {      if (DECL_BUILT_IN (olddecl))	{	  /* Get rid of any built-in function if new arg types don't match it	     or if we have a function definition.  */	  if (! types_match || new_is_definition)	    {	      if (! different_binding_level)		{		  TREE_TYPE (olddecl) = TREE_TYPE (newdecl);		  DECL_BUILT_IN (olddecl) = 0;		}	    }	  else	    {	      /* If redeclaring a builtin function, and not a definition,		 it stays built in.  */	      DECL_BUILT_IN (newdecl) = 1;	      DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);	    }	}      /* Also preserve various other info from the definition.  */      else if (! new_is_definition)	DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);      if (! new_is_definition)	{	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);	  /* When called with different_binding_level set, don't copy over	     DECL_INITIAL, so that we don't accidentally change function	     declarations into function definitions.  */	  if (! different_binding_level)	    DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);	  DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);	  if (DECL_INLINE (newdecl))	    DECL_ABSTRACT_ORIGIN (newdecl) = olddecl;	}    }  if (different_binding_level)    {      /* Don't output a duplicate symbol for this declaration.  */      TREE_ASM_WRITTEN (newdecl) = 1;      return 0;    }  /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.     But preserve OLDdECL's DECL_UID.  */  {    register unsigned olddecl_uid = DECL_UID (olddecl);    bcopy ((char *) newdecl + sizeof (struct tree_common),	   (char *) olddecl + sizeof (struct tree_common),	   sizeof (struct tree_decl) - sizeof (struct tree_common));    DECL_UID (olddecl) = olddecl_uid;  }  return 1;}/* Record a decl-node X as belonging to the current lexical scope.   Check for errors (such as an incompatible declaration for the same   name already seen in the same scope).   Returns either X or an old decl for the same name.   If an old decl is returned, it may have been smashed   to agree with what X says.  */treepushdecl (x)     tree x;{  register tree t;  register tree name = DECL_NAME (x);  register struct binding_level *b = current_binding_level;  DECL_CONTEXT (x) = current_function_decl;  /* A local extern declaration for a function doesn't constitute nesting.     A local auto declaration does, since it's a forward decl     for a nested function coming later.  */  if (TREE_CODE (x) == FUNCTION_DECL && DECL_INITIAL (x) == 0      && DECL_EXTERNAL (x))    DECL_CONTEXT (x) = 0;  if (warn_nested_externs && DECL_EXTERNAL (x) && b != global_binding_level      && x != IDENTIFIER_IMPLICIT_DECL (name)      /* Don't print error messages for __FUNCTION__ and __PRETTY_FUNCTION__ */      && !DECL_IN_SYSTEM_HEADER (x))    warning ("nested extern declaration of `%s'", IDENTIFIER_POINTER (name));  if (name)    {      char *file;      int line;      int different_binding_level = 0;      t = lookup_name_current_level (name);      /* Don't type check externs here when -traditional.  This is so that	 code with conflicting declarations inside blocks will get warnings	 not errors.  X11 for instance depends on this.  */      if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional)	{	  t = IDENTIFIER_GLOBAL_VALUE (name);	  /* Type decls at global scope don't conflict with externs declared	     inside lexical blocks.  */	  if (t && TREE_CODE (t) == TYPE_DECL)	    t = 0;	  different_binding_level = 1;	}      if (t != 0 && t == error_mark_node)	/* error_mark_node is 0 for a while during initializ

⌨️ 快捷键说明

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