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

📄 decl.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
static treelookup_name_current_level (name)     tree name;{  register tree t;  if (current_binding_level == global_binding_level)    return IDENTIFIER_GLOBAL_VALUE (name);  if (IDENTIFIER_LOCAL_VALUE (name) == 0)    return 0;  for (t = current_binding_level->names; t; t = TREE_CHAIN (t))    if (DECL_NAME (t) == name)      break;  return t;}/* Use a binding level to record a labeled block declaration */voidpush_labeled_block (lb)    tree lb;{  register tree name = DECL_NAME (LABELED_BLOCK_LABEL (lb));  register struct binding_level *b = current_binding_level;  tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);  if (oldlocal != 0)      b->shadowed = tree_cons (name, oldlocal, b->shadowed);  TREE_CHAIN (lb) = b->names;  b->names = lb;  IDENTIFIER_LOCAL_VALUE (name) = lb;}/* Pop the current binding level, reinstalling values for the previous   labeled block */voidpop_labeled_block (){  struct binding_level *b = current_binding_level;  tree label =  b->names;  IDENTIFIER_LOCAL_VALUE (DECL_NAME (LABELED_BLOCK_LABEL (label))) =     NULL_TREE;  if (b->shadowed)    IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (b->shadowed)) =       TREE_VALUE (b->shadowed);  /* Pop the current level, and free the structure for reuse.  */  current_binding_level = current_binding_level->level_chain;  b->level_chain = free_binding_level;  free_binding_level = b;}/* 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;  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 we're naming a hitherto-unnamed type, set its TYPE_NAME	 to point to the TYPE_DECL.	 Since Java does not have typedefs, a type can only have	 one (true) name, given by a class, interface, or builtin. */      if (TREE_CODE (x) == TYPE_DECL	  && TYPE_NAME (TREE_TYPE (x)) == 0	  && TREE_TYPE (x) != error_mark_node)	{	  TYPE_NAME (TREE_TYPE (x)) = x;	  TYPE_STUB_DECL (TREE_TYPE (x)) = x;	}      /* This name is new in its binding level.	 Install the new declaration and return it.  */      if (b == global_binding_level)	{	  /* Install a global value.  */	  	  IDENTIFIER_GLOBAL_VALUE (name) = x;	}      else	{	  /* Here to install a non-global value.  */	  tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);	  IDENTIFIER_LOCAL_VALUE (name) = x;#if 0	  /* Warn if shadowing an argument at the top level of the body.  */	  if (oldlocal != 0 && !DECL_EXTERNAL (x)	      /* This warning doesn't apply to the parms of a nested fcn.  */	      && ! current_binding_level->parm_flag	      /* Check that this is one level down from the parms.  */	      && current_binding_level->level_chain->parm_flag	      /* Check that the decl being shadowed		 comes from the parm level, one level up.  */	      && chain_member (oldlocal, current_binding_level->level_chain->names))	    {	      if (TREE_CODE (oldlocal) == PARM_DECL)		pedwarn ("declaration of `%s' shadows a parameter",			 IDENTIFIER_POINTER (name));	      else		pedwarn ("declaration of `%s' shadows a symbol from the parameter list",			 IDENTIFIER_POINTER (name));	    }	  /* Maybe warn if shadowing something else.  */	  else if (warn_shadow && !DECL_EXTERNAL (x)		   /* No shadow warnings for internally generated vars.  */		   && DECL_SOURCE_LINE (x) != 0		   /* No shadow warnings for vars made for inlining.  */		   && ! DECL_FROM_INLINE (x))	    {	      char *warnstring = 0;	      if (TREE_CODE (x) == PARM_DECL		  && current_binding_level->level_chain->parm_flag)		/* Don't warn about the parm names in function declarator		   within a function declarator.		   It would be nice to avoid warning in any function		   declarator in a declaration, as opposed to a definition,		   but there is no way to tell it's not a definition.  */		;	      else 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		       && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)		warnstring = "declaration of `%s' shadows global declaration";	      if (warnstring)		warning (warnstring, IDENTIFIER_POINTER (name));	    }#endif	  /* 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);	}    }  /* Put decls on list in reverse order.     We will reverse them later if necessary.  */  TREE_CHAIN (x) = b->names;  b->names = x;  return x;}voidpushdecl_force_head (x)     tree x;{  current_binding_level->names = x;}/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate.  */treepushdecl_top_level (x)     tree x;{  register tree t;  register struct binding_level *b = current_binding_level;  current_binding_level = global_binding_level;  t = pushdecl (x);  current_binding_level = b;  return t;}/* Nonzero if we are currently in the global binding level.  */intglobal_bindings_p (){  return current_binding_level == global_binding_level;}/* Return the list of declarations of the current level.   Note that this list is in reverse order unless/until   you nreverse it; and when you do nreverse it, you must   store the result back using `storedecls' or you will lose.  */treegetdecls (){  return current_binding_level->names;}/* Create a new `struct binding_level'.  */staticstruct binding_level *make_binding_level (){  /* NOSTRICT */  return (struct binding_level *) xmalloc (sizeof (struct binding_level));}voidpushlevel (unused)  int unused ATTRIBUTE_UNUSED;{  register struct binding_level *newlevel = NULL_BINDING_LEVEL;#if 0  /* If this is the top level of a function,     just make sure that NAMED_LABELS is 0.  */  if (current_binding_level == global_binding_level)    named_labels = 0;#endif  /* 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->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 BLOCK 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 BLOCK.  */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 subblocks = current_binding_level->blocks;  tree block = 0;  tree decl;  int block_previously_created;  keep |= current_binding_level->keep;  /* 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;  /* Output any nested inline functions within this block     if they weren't already output.  */  for (decl = decls; decl; decl = TREE_CHAIN (decl))    if (TREE_CODE (decl) == FUNCTION_DECL	&& ! TREE_ASM_WRITTEN (decl)	&& DECL_INITIAL (decl) != 0	&& TREE_ADDRESSABLE (decl))      {	/* If this decl was copied from a file-scope decl	   on account of a block-scope extern decl,	   propagate TREE_ADDRESSABLE to the file-scope decl.	   DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is	   true, since then the decl goes through save_for_inline_copying.  */	if (DECL_ABSTRACT_ORIGIN (decl) != 0	    && DECL_ABSTRACT_ORIGIN (decl) != decl)	  TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;	else	  {	    push_function_context ();	    output_inline_function (decl);	    pop_function_context ();	  }      }  /* If there were any declarations in that level,     or if this level is a function body,     create a BLOCK to record them for the life of this function.  */  block = 0;  block_previously_created = (current_binding_level->this_block != 0);  if (block_previously_created)    block = current_binding_level->this_block;  else if (keep || functionbody	   || (current_binding_level->keep_if_subblocks && subblocks != 0))    block = make_node (BLOCK);  if (block != 0)    {      BLOCK_VARS (block) = decls;      BLOCK_TYPE_TAGS (block) = NULL_TREE;      BLOCK_SUBBLOCKS (block) = subblocks;      remember_end_note (block);    }  /* In each subblock, record that this is its superior.  */  for (link = subblocks; link; link = TREE_CHAIN (link))    BLOCK_SUPERCONTEXT (link) = block;  /* Clear out the meanings of the local variables of this level.  */  for (link = decls; link; link = TREE_CHAIN (link))    {      tree name = DECL_NAME (link);      if (name != 0 && IDENTIFIER_LOCAL_VALUE (name) == link)	{	  /* If the ident. was used or addressed via a local extern decl,	     don't forget that fact.  */	  if (DECL_EXTERNAL (link))	    {	      if (TREE_USED (link))		TREE_USED (name) = 1;	      if (TREE_ADDRESSABLE (link))		TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;	    }	  IDENTIFIER_LOCAL_VALUE (name) = 0;	}    }  /* 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, and clear out the current     (function local) meanings of their names.  */  if (functionbody)    {      /* If this is the top level block of a function,	 the vars are the function's parameters.	 Don't leave them in the BLOCK because they are	 found in the FUNCTION_DECL instead.  */      BLOCK_VARS (block) = 0;      /* Clear out the definitions of all label names,	 since their scopes end here,	 and add them to BLOCK_VARS.  */#if 0      for (link = named_labels; link; link = TREE_CHAIN (link))	{	  register tree label = TREE_VALUE (link);	  if (DECL_INITIAL (label) == 0)	    {	      error_with_decl (label, "label `%s' used but not defined");	      /* Avoid crashing later.  */	      define_label (input_filename, lineno,			    DECL_NAME (label));	    }	  else if (warn_unused && !TREE_USED (label))	    warning_with_decl (label, "label `%s' defined but not used");

⌨️ 快捷键说明

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