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

📄 c-decl.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	  else if (TREE_CODE (olddecl) == FUNCTION_DECL		   && DECL_INITIAL (olddecl) != 0		   && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) == 0		   && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0)	    {	      /* Prototype decl follows defn w/o prototype.  */	      warning_with_decl (newdecl, "prototype for `%s'");	      warning_with_decl (olddecl,				 "follows non-prototype definition here");	    }	  /* These bits are logically part of the type.  */	  if (pedantic	      && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)		  || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))	    warning_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl");	}    }  if (TREE_CODE (olddecl) == TREE_CODE (newdecl))    {      int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL			       && DECL_INITIAL (newdecl) != 0);      /* Copy all the DECL_... slots specified in the new decl	 except for any that we copy here from the old type.  */      if (types_match)	{	  tree oldtype = TREE_TYPE (olddecl);	  /* Merge the data types specified in the two decls.  */	  TREE_TYPE (newdecl)	    = TREE_TYPE (olddecl)	      = commontype (TREE_TYPE (newdecl), TREE_TYPE (olddecl));	  /* 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);	      DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);	      if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))		DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);	    }	  /* Merge the type qualifiers.  */	  if (TREE_READONLY (newdecl))	    TREE_READONLY (olddecl) = 1;	  if (TREE_THIS_VOLATILE (newdecl))	    TREE_THIS_VOLATILE (olddecl) = 1;	  /* Merge the initialization information.  */	  if (DECL_INITIAL (newdecl) == 0)	    DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);	  /* Keep the old rtl since we can safely use it.  */	  DECL_RTL (newdecl) = DECL_RTL (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_VOLATILE (olddecl) = TREE_VOLATILE (newdecl);	}      /* Merge the storage class information.  */      if (TREE_EXTERNAL (newdecl))	{	  TREE_STATIC (newdecl) = TREE_STATIC (olddecl);	  TREE_EXTERNAL (newdecl) = TREE_EXTERNAL (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.  */	      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;	    }	  else	    TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);	}      else	{	  TREE_STATIC (olddecl) = TREE_STATIC (newdecl);	  TREE_EXTERNAL (olddecl) = 0;	  TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);	}      /* If either decl says `inline', this fn is inline,	 unless its definition was passed already.  */      if (TREE_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)	TREE_INLINE (olddecl) = 1;      /* If redeclaring a builtin function, and not a definition,	 it stays built in.	 Also preserve various other info from the definition.  */      if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)	{	  DECL_SET_FUNCTION_CODE (newdecl, DECL_FUNCTION_CODE (olddecl));	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);	  DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);	  DECL_RESULT_TYPE (newdecl) = DECL_RESULT_TYPE (olddecl);	  DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);	  DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);	}      /* Don't lose track of having output OLDDECL as GDB symbol.  */      DECL_BLOCK_SYMTAB_ADDRESS (newdecl)	= DECL_BLOCK_SYMTAB_ADDRESS (olddecl);      bcopy ((char *) newdecl + sizeof (struct tree_common),	     (char *) olddecl + sizeof (struct tree_common),	     sizeof (struct tree_decl) - sizeof (struct tree_common));      return 1;    }  /* New decl is completely inconsistent with the old one =>     tell caller to replace the old one.  */  return 0;}/* 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;  if (name)    {      char *file;      int line;      t = lookup_name_current_level (name);      if (t != 0 && t == error_mark_node)	/* error_mark_node is 0 for a while during initialization!  */	{	  t = 0;	  error_with_decl (x, "`%s' used prior to declaration");	}      if (t != 0)	{	  file = DECL_SOURCE_FILE (t);	  line = DECL_SOURCE_LINE (t);	}      if (t != 0 && duplicate_decls (x, t))	{	  /* If this decl is `static' and an implicit decl was seen previously,	     warn.  But don't complain if -traditional,	     since traditional compilers don't complain.  */	  if (!flag_traditional && TREE_PUBLIC (name)	      && ! TREE_PUBLIC (x) && ! TREE_EXTERNAL (x)	      /* We used to warn also for explicit extern followed by static,		 but sometimes you need to do it that way.  */	      && IDENTIFIER_IMPLICIT_DECL (name) != 0)	    {	      warning ("`%s' was declared implicitly `extern' and later `static'",		       IDENTIFIER_POINTER (name));	      warning_with_file_and_line (file, line,					  "previous declaration of `%s'",					  IDENTIFIER_POINTER (name));	    }	  return t;	}      /* If declaring a type as a typedef, and the type has no known	 typedef name, install this TYPE_DECL as its typedef name.  */      if (TREE_CODE (x) == TYPE_DECL)	if (TYPE_NAME (TREE_TYPE (x)) == 0)	  TYPE_NAME (TREE_TYPE (x)) = x;      /* Multiple external decls of the same identifier ought to match.  */      if (TREE_EXTERNAL (x) && IDENTIFIER_GLOBAL_VALUE (name) != 0	  && (TREE_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name))	      || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name))))	{	  if (! comptypes (TREE_TYPE (x),			   TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name))))	    {	      warning_with_decl (x,				 "type mismatch with previous external decl");	      warning_with_decl (IDENTIFIER_GLOBAL_VALUE (name),				 "previous external decl of `%s'");	    }	}      /* In PCC-compatibility mode, extern decls of vars with no current decl	 take effect at top level no matter where they are.  */      if (flag_traditional && TREE_EXTERNAL (x)	  && lookup_name (name) == 0)	{	  tree type = TREE_TYPE (x);	  /* But don't do this if the type contains temporary nodes.  */	  while (type)	    {	      if (! TREE_PERMANENT (type))		{		  warning_with_decl (x, "Type of `extern' decl is not global");		  break;		}	      else if (TREE_CODE (type) == FUNCTION_TYPE		       && TYPE_ARG_TYPES (type) != 0)		/* The types might not be truly local,		   but the list of arg types certainly is temporary.		   Since prototypes are nontraditional,		   ok not to do the traditional thing.  */		break;	      type = TREE_TYPE (type);	    }	  if (type == 0)	    b = global_binding_level;	}      /* This name is new in its binding level.	 Install the new declaration and return it.  */      if (b == global_binding_level)	{	  /* Install a global value.  */	  	  /* If the first global decl has external linkage,	     warn if we later see static one.  */	  if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x))	    TREE_PUBLIC (name) = 1;	  IDENTIFIER_GLOBAL_VALUE (name) = x;	  /* Don't forget if the function was used via an implicit decl.  */	  if (IDENTIFIER_IMPLICIT_DECL (name)	      && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))	    TREE_USED (x) = 1, TREE_USED (name) = 1;	  /* Don't forget if its address was taken in that way.  */	  if (IDENTIFIER_IMPLICIT_DECL (name)	      && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name)))	    TREE_ADDRESSABLE (x) = 1;	  /* Warn about mismatches against previous implicit decl.  */	  if (IDENTIFIER_IMPLICIT_DECL (name) != 0	      /* If this real decl matches the implicit, don't complain.  */	      && ! (TREE_CODE (x) == FUNCTION_DECL		    && TREE_TYPE (TREE_TYPE (x)) == integer_type_node))	    warning ("`%s' was previously implicitly declared to return `int'",		     IDENTIFIER_POINTER (name));	  /* If this decl is `static' and an `extern' was seen previously,	     that is erroneous.  */	  if (TREE_PUBLIC (name)	      && ! TREE_PUBLIC (x) && ! TREE_EXTERNAL (x))	    {	      if (IDENTIFIER_IMPLICIT_DECL (name))		warning ("`%s' was declared implicitly `extern' and later `static'",			 IDENTIFIER_POINTER (name));	      else		warning ("`%s' was declared `extern' and later `static'",			 IDENTIFIER_POINTER (name));	    }	}      else	{	  /* Here to install a non-global value.  */	  tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);	  tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name);	  IDENTIFIER_LOCAL_VALUE (name) = x;	  /* If this is an extern function declaration, see if we	     have a global definition for the function.  */	  if (oldlocal == 0	      && oldglobal != 0	      && TREE_CODE (x) == FUNCTION_DECL	      && TREE_CODE (oldglobal) == FUNCTION_DECL)	    {	      /* We have one.  Their types must agree.  */	      if (! comptypes (TREE_TYPE (x),			       TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name))))		warning_with_decl (x, "local declaration of `%s' doesn't match global one");	      /* If the global one is inline, make the local one inline.  */	      else if (TREE_INLINE (oldglobal)		       || DECL_FUNCTION_CODE (oldglobal) != NOT_BUILT_IN		       || (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != 0			   && TYPE_ARG_TYPES (TREE_TYPE (x)) == 0))		IDENTIFIER_LOCAL_VALUE (name) = oldglobal;	    }	  /* If we have a local external declaration,	     and no file-scope declaration has yet been seen,	     then if we later have a file-scope decl it must not be static.  */	  if (oldlocal == 0	      && oldglobal == 0	      && TREE_EXTERNAL (x)	      && TREE_PUBLIC (x))	    {	      TREE_PUBLIC (name) = 1;	    }	  /* Warn if shadowing an argument at the top level of the body.  */	  if (oldlocal != 0 && !TREE_EXTERNAL (x)	      && TREE_CODE (oldlocal) == PARM_DECL	      && TREE_CODE (x) != PARM_DECL	      && current_binding_level->level_chain->parm_flag)	    warning ("declaration of `%s' shadows a parameter",		     IDENTIFIER_POINTER (name));	  /* Maybe warn if shadowing something else.  */	  else if (warn_shadow && !TREE_EXTERNAL (x)		   /* No shadow warnings for vars made for inlining.  */		   && !TREE_INLINE (x))	    {	      char *warnstring = 0;	      if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL)		warnstring = "declaration of `%s' shadows a parameter";	      else if (oldlocal != 0)		warnstring = "declaration of `%s' shadows previous local";	      else if (IDENTIFIER_GLOBAL_VALUE (name) != 0)		warnstring = "declaration of `%s' shadows global declaration";	      if (warnstring)		warning (warnstring, IDENTIFIER_POINTER (name));	    }	  /* If storing a local value, there may already be one (inherited).	     If so, record it for restoration when this binding level ends.  */	  if (oldlocal != 0)	    b->shadowed = tree_cons (name, oldlocal, b->shadowed);	}      /* Keep count of variables in this level with incomplete type.  */      if (TYPE_SIZE (TREE_TYPE (x)) == 0)	++b->n_incomplete;    }  /* Put decls on list in reverse order.     We will reverse them later if necessary.  */  TREE_CHAIN (x) = b->names;  b->names = x;  return x;}/* Generate an implicit declaration for identifier FUNCTIONID   as a function of type int ().  Print a warning if appropriate.  */treeimplicitly_declare (functionid)     tree functionid;{  register tree decl;  /* Save the decl permanently so we can warn if definition follows.  */#if 0  /* A temporary implicit decl causes a crash in pushdecl.	  In 1.38, fix pushdecl.  */  if (flag_traditional || !warn_implicit      || current_binding_level == global_binding_level)#endif    end_temporary_allocation ();  /* We used to reuse an old implicit decl here,     but this loses with inline functions because it can clobber     the saved decl chains.  *//*  if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0)    decl = IDENTIFIER_IMPLICIT_DECL (functionid);  else  */    decl = build_decl (FUNCTION_DECL, functionid, default_function_type);  TREE_EXTERNAL (decl) = 1;  TREE_PUBLIC (decl) = 1;  /* ANSI standard says implicit declarations are in the innermost block.     So we record the decl in the standard fashion.     If flag_traditional is set, pushdecl does it top-level.  */  pushdecl (decl);  rest_of_decl_compilation (decl, 0, 0, 0);  if (warn_implicit      /* Only one warning per identifier.  */      && IDENTIFIER_IMPLICIT_DECL (functionid) == 0)    warning ("implicit declaration of function `%s'",	     IDENTIFIER_POINTER (functionid));  IDENTIFIER_IMPLICIT_DECL (functionid) = decl;#if 0  if (flag_traditional || ! warn_implicit      || current_binding_level == global_binding_level)#endif    resume_temporary_allocation ();

⌨️ 快捷键说明

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