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

📄 c-decl.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
     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;  tree decl;  int block_previously_created;  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;  /* 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.  */	if (DECL_ABSTRACT_ORIGIN (decl) != 0)	  TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;	else	  output_inline_function (decl);      }  /* If there were any declarations or structure tags 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) = tags;      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))    {      if (DECL_NAME (link) != 0)	{	  /* 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 (DECL_NAME (link)) = 1;	      if (TREE_ADDRESSABLE (link))		TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;	    }	  IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 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.  */      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");	  IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;	  /* Put the labels into the "variables" of the	     top-level block, so debugger can see them.  */	  TREE_CHAIN (label) = BLOCK_VARS (block);	  BLOCK_VARS (block) = label;	}    }  /* 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;  }  /* Dispose of the block that we just made inside some higher level.  */  if (functionbody)    DECL_INITIAL (current_function_decl) = block;  else if (block)    {      if (!block_previously_created)        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);  /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this     binding contour so that they point to the appropriate construct, i.e.     either to the current FUNCTION_DECL node, or else to the BLOCK node     we just constructed.     Note that for tagged types whose scope is just the formal parameter     list for some function type specification, we can't properly set     their TYPE_CONTEXTs here, because we don't have a pointer to the     appropriate FUNCTION_TYPE node readily available to us.  For those     cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set     in `grokdeclarator' as soon as we have created the FUNCTION_TYPE     node which will represent the "scope" for these "parameter list local"     tagged types.  */  if (functionbody)    for (link = tags; link; link = TREE_CHAIN (link))      TYPE_CONTEXT (TREE_VALUE (link)) = current_function_decl;  else if (block)    for (link = tags; link; link = TREE_CHAIN (link))      TYPE_CONTEXT (TREE_VALUE (link)) = block;  if (block)    TREE_USED (block) = 1;  return block;}/* Delete the node BLOCK from the current binding level.   This is used for the block inside a stmt expr ({...})   so that the block can be reinserted where appropriate.  */voiddelete_block (block)     tree block;{  tree t;  if (current_binding_level->blocks == block)    current_binding_level->blocks = TREE_CHAIN (block);  for (t = current_binding_level->blocks; t;)    {      if (TREE_CHAIN (t) == block)	TREE_CHAIN (t) = TREE_CHAIN (block);      else	t = TREE_CHAIN (t);    }  TREE_CHAIN (block) = NULL;  /* Clear TREE_USED which is always set by poplevel.     The flag is set again if insert_block is called.  */  TREE_USED (block) = 0;}/* Insert BLOCK at the end of the list of subblocks of the   current binding level.  This is used when a BIND_EXPR is expanded,   to handle the BLOCK node inside teh BIND_EXPR.  */voidinsert_block (block)     tree block;{  TREE_USED (block) = 1;  current_binding_level->blocks    = chainon (current_binding_level->blocks, block);}/* Set the BLOCK node for the innermost scope   (the one we are currently in).  */voidset_block (block)     register tree block;{  current_binding_level->this_block = block;}voidpush_label_level (){  register struct binding_level *newlevel;  /* 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 label levels.  */  newlevel->level_chain = label_level_chain;  label_level_chain = newlevel;  newlevel->names = named_labels;  newlevel->shadowed = shadowed_labels;  named_labels = 0;  shadowed_labels = 0;}voidpop_label_level (){  register struct binding_level *level = label_level_chain;  tree link, prev;  /* Clear out the definitions of the declared labels in this level.     Leave in the list any ordinary, non-declared labels.  */  for (link = named_labels, prev = 0; link;)    {      if (C_DECLARED_LABEL_FLAG (TREE_VALUE (link)))	{	  if (DECL_SOURCE_LINE (TREE_VALUE (link)) == 0)	    {	      error_with_decl ("label `%s' used but not defined",			       TREE_VALUE (link));	      /* Avoid crashing later.  */	      define_label (input_filename, lineno,			    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;	  /* Delete this element from the list.  */	  link = TREE_CHAIN (link);	  if (prev)	    TREE_CHAIN (prev) = link;	  else	    named_labels = link;	}      else	{	  prev = link;	  link = TREE_CHAIN (link);	}    }  /* Bring back all the labels that were shadowed.  */  for (link = shadowed_labels; link; link = TREE_CHAIN (link))    if (DECL_NAME (TREE_VALUE (link)) != 0)      IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))	= TREE_VALUE (link);  named_labels = chainon (named_labels, level->names);  shadowed_labels = level->shadowed;  /* Pop the current level, and free the structure for reuse.  */  label_level_chain = label_level_chain->level_chain;  level->level_chain = free_binding_level;  free_binding_level = level;}/* Push a definition or a declaration 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;  /* Find the proper binding level for this type tag.  */  for (b = current_binding_level; b->tag_transparent; b = b->level_chain)    continue;  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);  /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the     tagged type we just added to the current binding level.  This fake     NULL-named TYPE_DECL node helps dwarfout.c to know when it needs     to output a representation of a tagged type, and it also gives     us a convenient place to record the "scope start" address for the     tagged type.  */  TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type));}/* 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));  int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL			   && DECL_INITIAL (newdecl) != 0);  tree oldtype = TREE_TYPE (olddecl);  tree newtype = TREE_TYPE (newdecl);  if (TREE_CODE (newtype) == ERROR_MARK      || TREE_CODE (oldtype) == ERROR_MARK)    types_match = 0;  /* New decl is completely inconsistent with the old one =>     tell caller to replace the old one.     This is always an error except in the case of shadowing a builtin.  */  if (TREE_CODE (olddecl) != TREE_CODE (newdecl))    {      if (TREE_CODE (olddecl) == FUNCTION_DECL	  && DECL_BUILT_IN (olddecl))

⌨️ 快捷键说明

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