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

📄 decl.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* Resume the variable caches.  */  decls = current_binding_level->names;  /* Restore the meanings of the local variables of this level.  */  for (link = decls; link; link = TREE_CHAIN (link))    {      /* If it doesn't have a name, there is nothing left to do with it.  */      if (DECL_NAME (link) == NULL_TREE)	continue;      IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = link;      /* If this is a TYPE_DECL, push it into the type value slot.  */      if (TREE_CODE (link) == TYPE_DECL)	SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (link), TREE_TYPE (link));    }}/* 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_TREE;  /* 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 the BIND_EXPR.  */voidinsert_block (block)     tree block;{  TREE_USED (block) = 1;  current_binding_level->blocks    = chainon (current_binding_level->blocks, block);}/* Add BLOCK to the current list of blocks for this binding contour.  */voidadd_block_current_level (block)     tree block;{  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;}/* Do a pushlevel for class declarations.  */voidpushlevel_class (){  register struct binding_level *newlevel;  /* Reuse or create a struct for this binding level.  */#if defined(DEBUG_CP_BINDING_LEVELS)  if (0)#else /* !defined(DEBUG_CP_BINDING_LEVELS) */  if (free_binding_level)#endif /* !defined(DEBUG_CP_BINDING_LEVELS) */    {      newlevel = free_binding_level;      free_binding_level = free_binding_level->level_chain;    }  else    {      newlevel = make_binding_level ();    }#if defined(DEBUG_CP_BINDING_LEVELS)  is_class_level = 1;#endif /* defined(DEBUG_CP_BINDING_LEVELS) */  push_binding_level (newlevel, 0, 0);  decl_stack = push_decl_level (decl_stack, &decl_obstack);  class_binding_level = current_binding_level;  class_binding_level->parm_flag = 2;  /* We have just pushed into a new binding level.  Now, fake out the rest     of the compiler.  Set the `current_binding_level' back to point to     the most closely containing non-class binding level.  */  do    {      current_binding_level = current_binding_level->level_chain;    }  while (current_binding_level->parm_flag == 2);}/* ...and a poplevel for class declarations.  FORCE is used to force   clearing out of CLASS_VALUEs after a class definition.  */treepoplevel_class (force)     int force;{  register struct binding_level *level = class_binding_level;  tree block = NULL_TREE;  tree shadowed;  my_friendly_assert (level != 0, 354);    decl_stack = pop_stack_level (decl_stack);  for (shadowed = level->shadowed; shadowed; shadowed = TREE_CHAIN (shadowed))    IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed);  /* If we're leaving a toplevel class, don't bother to do the setting     of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot     shouldn't even be used when current_class_type isn't set, and second,     if we don't touch it here, we're able to use the cache effect if the     next time we're entering a class scope, it is the same class.  */  if (current_class_depth != 1 || force)    for (shadowed = level->class_shadowed;	 shadowed;	 shadowed = TREE_CHAIN (shadowed))      IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed);  else    /* Remember to save what IDENTIFIER's were bound in this scope so we       can recover from cache misses.  */    {      previous_class_type = current_class_type;      previous_class_values = class_binding_level->class_shadowed;    }  for (shadowed = level->type_shadowed;       shadowed;       shadowed = TREE_CHAIN (shadowed))    IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed);  GNU_xref_end_scope ((HOST_WIDE_INT) class_binding_level,		      (HOST_WIDE_INT) class_binding_level->level_chain,		      class_binding_level->parm_flag,		      class_binding_level->keep);  if (class_binding_level->parm_flag != 2)    class_binding_level = (struct binding_level *)0;  /* Now, pop out of the the binding level which we created up in the     `pushlevel_class' routine.  */#if defined(DEBUG_CP_BINDING_LEVELS)  is_class_level = 1;#endif /* defined(DEBUG_CP_BINDING_LEVELS) */  pop_binding_level ();  return block;}/* For debugging.  */static int no_print_functions = 0;static int no_print_builtins = 0;voidprint_binding_level (lvl)     struct binding_level *lvl;{  tree t;  int i = 0, len;  fprintf (stderr, " blocks=");  fprintf (stderr, HOST_PTR_PRINTF, lvl->blocks);  fprintf (stderr, " n_incomplete=%d parm_flag=%d keep=%d",	   list_length (lvl->incomplete), lvl->parm_flag, lvl->keep);  if (lvl->tag_transparent)    fprintf (stderr, " tag-transparent");  if (lvl->more_cleanups_ok)    fprintf (stderr, " more-cleanups-ok");  if (lvl->have_cleanups)    fprintf (stderr, " have-cleanups");  fprintf (stderr, "\n");  if (lvl->names)    {      fprintf (stderr, " names:\t");      /* We can probably fit 3 names to a line?  */      for (t = lvl->names; t; t = TREE_CHAIN (t))	{	  if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL)) 	    continue;	  if (no_print_builtins	      && (TREE_CODE (t) == TYPE_DECL)	      && (!strcmp (DECL_SOURCE_FILE (t),"<built-in>")))	    continue;	  /* Function decls tend to have longer names.  */	  if (TREE_CODE (t) == FUNCTION_DECL)	    len = 3;	  else	    len = 2;	  i += len;	  if (i > 6)	    {	      fprintf (stderr, "\n\t");	      i = len;	    }	  print_node_brief (stderr, "", t, 0);	  if (t == error_mark_node)	    break;	}      if (i)        fprintf (stderr, "\n");    }  if (lvl->tags)    {      fprintf (stderr, " tags:\t");      i = 0;      for (t = lvl->tags; t; t = TREE_CHAIN (t))	{	  if (TREE_PURPOSE (t) == NULL_TREE)	    len = 3;	  else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t)))	    len = 2;	  else	    len = 4;	  i += len;	  if (i > 5)	    {	      fprintf (stderr, "\n\t");	      i = len;	    }	  if (TREE_PURPOSE (t) == NULL_TREE)	    {	      print_node_brief (stderr, "<unnamed-typedef", TREE_VALUE (t), 0);	      fprintf (stderr, ">");	    }	  else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t)))	    print_node_brief (stderr, "", TREE_VALUE (t), 0);	  else	    {	      print_node_brief (stderr, "<typedef", TREE_PURPOSE (t), 0);	      print_node_brief (stderr, "", TREE_VALUE (t), 0);	      fprintf (stderr, ">");	    }	}      if (i)	fprintf (stderr, "\n");    }  if (lvl->shadowed)    {      fprintf (stderr, " shadowed:");      for (t = lvl->shadowed; t; t = TREE_CHAIN (t))	{	  fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));	}      fprintf (stderr, "\n");    }  if (lvl->class_shadowed)    {      fprintf (stderr, " class-shadowed:");      for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t))	{	  fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));	}      fprintf (stderr, "\n");    }  if (lvl->type_shadowed)    {      fprintf (stderr, " type-shadowed:");      for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))        {	  fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));        }      fprintf (stderr, "\n");    }}voidprint_other_binding_stack (stack)     struct binding_level *stack;{  struct binding_level *level;  for (level = stack; level != global_binding_level; level = level->level_chain)    {      fprintf (stderr, "binding level ");      fprintf (stderr, HOST_PTR_PRINTF, level);      fprintf (stderr, "\n");      print_binding_level (level);    }}voidprint_binding_stack (){  struct binding_level *b;  fprintf (stderr, "current_binding_level=");  fprintf (stderr, HOST_PTR_PRINTF, current_binding_level);  fprintf (stderr, "\nclass_binding_level=");  fprintf (stderr, HOST_PTR_PRINTF, class_binding_level);  fprintf (stderr, "\nglobal_binding_level=");  fprintf (stderr, HOST_PTR_PRINTF, global_binding_level);  fprintf (stderr, "\n");  if (class_binding_level)    {      for (b = class_binding_level; b; b = b->level_chain)	if (b == current_binding_level)	  break;      if (b)	b = class_binding_level;      else	b = current_binding_level;    }  else    b = current_binding_level;  print_other_binding_stack (b);  fprintf (stderr, "global:\n");  print_binding_level (global_binding_level);}extern char * first_global_object_name;/* Get a unique name for each call to this routine for unnamed namespaces.   Mostly copied from get_file_function_name.  */static treeget_unique_name (){  static int temp_name_counter = 0;  char *buf;  register char *p;  if (first_global_object_name)    p = first_global_object_name;  else if (main_input_filename)    p = main_input_filename;  else    p = input_filename;#define UNNAMED_NAMESPACE_FORMAT "__%s_%d"  buf = (char *) alloca (sizeof (UNNAMED_NAMESPACE_FORMAT) + strlen (p));  sprintf (buf, UNNAMED_NAMESPACE_FORMAT, p, temp_name_counter++);  /* Don't need to pull weird characters out of global names.  */  if (p != first_global_object_name)    {      for (p = buf+11; *p; p++)	if (! ((*p >= '0' && *p <= '9')#ifndef NO_DOLLAR_IN_LABEL	/* this for `$'; unlikely, but... -- kr */	       || *p == '$'#endif#ifndef NO_DOT_IN_LABEL		/* this for `.'; unlikely, but...  */	       || *p == '.'#endif	       || (*p >= 'A' && *p <= 'Z')	       || (*p >= 'a' && *p <= 'z')))	  *p = '_';    }  return get_identifier (buf);}/* Push into the scope of the NAME namespace.  If NAME is NULL_TREE, then we   select a name that is unique to this compilation unit.  */voidpush_namespace (name)     tree name;{#if 1  static int warned;  if (! warned)    sorry ("namespace");    warned = 1;#else  extern tree current_namespace;  tree old_id = get_namespace_id ();  char *buf;  tree d;  if (! name)    {      /* Create a truly ugly name! */      name = get_unique_name ();    }  d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);  /* Mark them as external, so redeclaration_error_message doesn't think     they are duplicates.  */  DECL_EXTERNAL (d) = 1;  d = pushdecl (d);  if (NAMESPACE_LEVEL (d) == 0)    {      /* This is new for this compilation unit.  */      pushlevel (0);      declare_namespace_level ();      NAMESPACE_LEVEL (d) = current_binding_level;    }  else    resume_level (NAMESPACE_LEVEL (d));  /* This code is just is bit old now...  */   current_namespace = tree_cons (NULL_TREE, name, current_namespace);  buf = (char *) alloca (4 + (old_id ? IDENTIFIER_LENGTH (old_id) : 0)			 + IDENTIFIER_LENGTH (name));  sprintf (buf, "%s%s", old_id ? IDENTIFIER_POINTER (old_id) : "",	   IDENTIFIER_POINTER (name));  TREE_PURPOSE (current_namespace) = get_identifier (buf);#endif}/* Pop from the scope of the current namespace.  */voidpop_namespace (){#if 0  extern tree current_namespace;  tree decls, link;  current_namespace = TREE_CHAIN (current_namespace);  /* Just in case we get out of sync.  */  if (! namespace_bindings_p ())    poplevel (0, 0, 0);  decls = current_binding_level->names;  /* Clear out the meanings of the local variables of this level.  */  for (link = decls; link; link = TREE_CHAIN (link))

⌨️ 快捷键说明

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