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

📄 c-decl.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    warn_strict_prototypes = 1;  else if (!strcmp (p, "-Wcomment"))    ; /* cpp handles this one.  */  else if (!strcmp (p, "-Wcomments"))    ; /* cpp handles this one.  */  else if (!strcmp (p, "-Wtrigraphs"))    ; /* cpp handles this one.  */  else if (!strcmp (p, "-Wall"))    {      extra_warnings = 1;      warn_implicit = 1;      warn_return_type = 1;      warn_unused = 1;      warn_switch = 1;    }  else    return 0;  return 1;}voidprint_lang_identifier (file, node, indent)     FILE *file;     tree node;     int indent;{  print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);  print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);  print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);  print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);  print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);}/* Create a new `struct binding_level'.  */staticstruct binding_level *make_binding_level (){  /* NOSTRICT */  return (struct binding_level *) xmalloc (sizeof (struct binding_level));}/* Nonzero if we are currently in the global binding level.  */intglobal_bindings_p (){  return current_binding_level == global_binding_level;}voidkeep_next_level (){  keep_next_level_flag = 1;}/* Nonzero if the current level needs to have a LET_STMT made.  */intkept_level_p (){  return ((current_binding_level->keep_if_subblocks	   && current_binding_level->blocks != 0)	  || current_binding_level->keep	  || current_binding_level->names != 0);}/* Identify this binding level as a level of parameters.  */voiddeclare_parm_level (){  current_binding_level->parm_flag = 1;}/* Nonzero if currently making parm declarations.  */in_parm_level_p (){  return current_binding_level->parm_flag;}/* Enter a new binding level.   If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,   not for that of tags.  */voidpushlevel (tag_transparent)     int tag_transparent;{  register struct binding_level *newlevel = NULL_BINDING_LEVEL;  /* If this is the top level of a function,     just make sure that NAMED_LABELS is 0.     They should have been set to 0 at the end of the previous function.  */  if (current_binding_level == global_binding_level)    {      if (named_labels)	abort ();    }  /* Reuse or create a struct for this binding level.  */  if (free_binding_level)    {      newlevel = free_binding_level;      free_binding_level = free_binding_level->level_chain;    }  else    {      newlevel = make_binding_level ();    }  /* Add this level to the front of the chain (stack) of levels that     are active.  */  *newlevel = clear_binding_level;  newlevel->level_chain = current_binding_level;  current_binding_level = newlevel;  newlevel->tag_transparent = tag_transparent;  newlevel->keep = keep_next_level_flag;  keep_next_level_flag = 0;  newlevel->keep_if_subblocks = keep_next_if_subblocks;  keep_next_if_subblocks = 0;}/* Exit a binding level.   Pop the level off, and restore the state of the identifier-decl mappings   that were in effect when this level was entered.   If KEEP is nonzero, this level had explicit declarations, so   and create a "block" (a LET_STMT node) for the level   to record its declarations and subblocks for symbol table output.   If FUNCTIONBODY is nonzero, this level is the body of a function,   so create a block as if KEEP were set and also clear out all   label names.   If REVERSE is nonzero, reverse the order of decls before putting   them into the LET_STMT.  */treepoplevel (keep, reverse, functionbody)     int keep;     int reverse;     int functionbody;{  register tree link;  /* The chain of decls was accumulated in reverse order.     Put it into forward order, just for cleanliness.  */  tree decls;  tree tags = current_binding_level->tags;  tree subblocks = current_binding_level->blocks;  tree block = 0;  keep |= current_binding_level->keep;  /* This warning is turned off because it causes warnings for     declarations like `extern struct foo *x'.  */#if 0  /* Warn about incomplete structure types in this level.  */  for (link = tags; link; link = TREE_CHAIN (link))    if (TYPE_SIZE (TREE_VALUE (link)) == 0)      {	tree type = TREE_VALUE (link);	char *errmsg;	switch (TREE_CODE (type))	  {	  case RECORD_TYPE:	    errmsg = "`struct %s' incomplete in scope ending here";	    break;	  case UNION_TYPE:	    errmsg = "`union %s' incomplete in scope ending here";	    break;	  case ENUMERAL_TYPE:	    errmsg = "`enum %s' incomplete in scope ending here";	    break;	  }	if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)	  error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type)));	else	  /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL.  */	  error (errmsg, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));      }#endif /* 0 */  /* Get the decls in the order they were written.     Usually current_binding_level->names is in reverse order.     But parameter decls were previously put in forward order.  */  if (reverse)    current_binding_level->names      = decls = nreverse (current_binding_level->names);  else    decls = current_binding_level->names;  /* If there were any declarations or structure tags in that level,     or if this level is a function body,     create a LET_STMT to record them for the life of this function.  */  if (keep || functionbody      || (current_binding_level->keep_if_subblocks && subblocks != 0))    block = build_let (0, 0, keep ? decls : 0,		       subblocks, 0, keep ? tags : 0);  /* In each subblock, record that this is its superior.  */  for (link = subblocks; link; link = TREE_CHAIN (link))    STMT_SUPERCONTEXT (link) = block;  /* Clear out the meanings of the local variables of this level;     also record in each decl which block it belongs to.  */  for (link = decls; link; link = TREE_CHAIN (link))    {      if (DECL_NAME (link) != 0)	{	  /* If the ident. was used via a local extern decl,	     don't forget that fact.  */	  if (TREE_USED (link) && TREE_EXTERNAL (link))	    TREE_USED (DECL_NAME (link)) = 1;	  IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;	}      DECL_CONTEXT (link) = block;    }  /* Restore all name-meanings of the outer levels     that were shadowed by this level.  */  for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))    IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);  /* If the level being exited is the top level of a function,     check over all the labels.  */  if (functionbody)    {      /* Clear out the definitions of all label names,	 since their scopes end here.  */      for (link = named_labels; link; link = TREE_CHAIN (link))	{	  if (DECL_SOURCE_LINE (TREE_VALUE (link)) == 0)	    {	      error ("label `%s' used somewhere above but not defined",		     IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (link))));	      /* Avoid crashing later.  */	      define_label (input_filename, 1, DECL_NAME (TREE_VALUE (link)));	    }	  else if (warn_unused && !TREE_USED (TREE_VALUE (link)))	    warning_with_decl (TREE_VALUE (link), 			       "label `%s' defined but not used");	  IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0;	}      named_labels = 0;    }  /* Pop the current level, and free the structure for reuse.  */  {    register struct binding_level *level = current_binding_level;    current_binding_level = current_binding_level->level_chain;    level->level_chain = free_binding_level;    free_binding_level = level;  }  if (functionbody)    {      DECL_INITIAL (current_function_decl) = block;      /* If this is the top level block of a function,	 the vars are the function's parameters.	 Don't leave them in the LET_STMT because they are	 found in the FUNCTION_DECL instead.  */      STMT_VARS (block) = 0;    }  else if (block)    current_binding_level->blocks      = chainon (current_binding_level->blocks, block);  /* If we did not make a block for the level just exited,     any blocks made for inner levels     (since they cannot be recorded as subblocks in that level)     must be carried forward so they will later become subblocks     of something else.  */  else if (subblocks)    current_binding_level->blocks      = chainon (current_binding_level->blocks, subblocks);  if (block)    TREE_USED (block) = 1;  return block;}/* Push a definition of struct, union or enum tag "name".   "type" should be the type node.   We assume that the tag "name" is not already defined.   Note that the definition may really be just a forward reference.   In that case, the TYPE_SIZE will be zero.  */voidpushtag (name, type)     tree name, type;{  register struct binding_level *b = current_binding_level;  while (b->tag_transparent) b = b->level_chain;  if (name)    {      /* Record the identifier as the type's name if it has none.  */      if (TYPE_NAME (type) == 0)	TYPE_NAME (type) = name;      if (b == global_binding_level)	b->tags = perm_tree_cons (name, type, b->tags);      else	b->tags = saveable_tree_cons (name, type, b->tags);    }}/* Handle when a new declaration NEWDECL   has the same name as an old one OLDDECL   in the same binding contour.   Prints an error message if appropriate.   If safely possible, alter OLDDECL to look like NEWDECL, and return 1.   Otherwise, return 0.  */static intduplicate_decls (newdecl, olddecl)     register tree newdecl, olddecl;{  int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl));  if (TREE_CODE (TREE_TYPE (newdecl)) == ERROR_MARK      || TREE_CODE (TREE_TYPE (olddecl)) == ERROR_MARK)    types_match = 0;  /* If this decl has linkage, and the old one does too, maybe no error.  */  if (TREE_CODE (olddecl) != TREE_CODE (newdecl))    {      error_with_decl (newdecl, "`%s' redeclared as different kind of symbol");      error_with_decl (olddecl, "previous declaration of `%s'");    }  else    {      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_FUNCTION_CODE (olddecl) != NOT_BUILT_IN) 	{ 	  if (!types_match) 	    error_with_decl (newdecl, "conflicting types for built-in function `%s'"); 	  else if (extra_warnings) 	    warning_with_decl (newdecl, "built-in function `%s' redeclared"); 	}      else if (!types_match)	{	  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 (TREE_TYPE (olddecl)),			    TREE_TYPE (TREE_TYPE (newdecl)))	      && ((TYPE_ARG_TYPES (TREE_TYPE (olddecl)) == 0		   && DECL_INITIAL (olddecl) == 0)		  ||		  (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) == 0		   && DECL_INITIAL (newdecl) == 0)))	    {	      /* Classify the problem further.  */	      register tree t = TYPE_ARG_TYPES (TREE_TYPE (olddecl));	      if (t == 0)		t = TYPE_ARG_TYPES (TREE_TYPE (newdecl));	      for (; t; t = TREE_CHAIN (t))		{		  register tree type = TREE_VALUE (t);		  if (TREE_CHAIN (t) == 0 && type != void_type_node)		    {		      error ("A parameter list with an ellipsis can't match");		      error ("an empty parameter name list declaration.");		      break;		    }		  if (type == float_type_node		      || (TREE_CODE (type) == INTEGER_TYPE			  && (TYPE_PRECISION (type)			      < TYPE_PRECISION (integer_type_node))))		    {		      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,			       "here is the previous declaration of `%s'");	    }

⌨️ 快捷键说明

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