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

📄 decl.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
}static voidresume_binding_level (b)     struct binding_level *b;{  /* Resuming binding levels is meant only for namespaces,     and those cannot nest into classes. */  my_friendly_assert(!class_binding_level, 386);  /* Also, resuming a non-directly nested namespace is a no-no.  */  my_friendly_assert(b->level_chain == current_binding_level, 386);  current_binding_level = b;#if defined(DEBUG_CP_BINDING_LEVELS)  b->binding_depth = binding_depth;  indent ();  fprintf (stderr, "resume %s level 0x%08x line %d\n",	   (is_class_level) ? "class" : "block", b, lineno);  is_class_level = 0;  binding_depth++;#endif /* defined(DEBUG_CP_BINDING_LEVELS) */}/* 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;}/* Return the innermost binding level that is not for a class scope.  */static struct binding_level *innermost_nonclass_level (){  struct binding_level *b;  b = current_binding_level;  while (b->parm_flag == 2)    b = b->level_chain;  return b;}/* Nonzero if we are currently in a toplevel binding level.  This   means either the global binding level or a namespace in a toplevel   binding level.  Since there are no non-toplevel namespace levels,   this really means any namespace or pseudo-global level.  We also   include a class whose context is toplevel.  */inttoplevel_bindings_p (){  struct binding_level *b = innermost_nonclass_level ();  return b->namespace_p || b->pseudo_global;}/* Nonzero if this is a namespace scope, or if we are defining a class   which is itself at namespace scope, or whose enclosing class is   such a class, etc.  */intnamespace_bindings_p (){  struct binding_level *b = innermost_nonclass_level ();  return b->namespace_p;}voidkeep_next_level (){  keep_next_level_flag = 1;}/* Nonzero if the current level needs to have a BLOCK made.  */intkept_level_p (){  return (current_binding_level->blocks != NULL_TREE	  || current_binding_level->keep	  || current_binding_level->names != NULL_TREE	  || (current_binding_level->tags != NULL_TREE	      && !current_binding_level->tag_transparent));}/* Identify this binding level as a level of parameters.  */voiddeclare_parm_level (){  current_binding_level->parm_flag = 1;}voiddeclare_pseudo_global_level (){  current_binding_level->pseudo_global = 1;}static voiddeclare_namespace_level (){  current_binding_level->namespace_p = 1;}intpseudo_global_level_p (){  struct binding_level *b = innermost_nonclass_level ();  return b->pseudo_global;}voidset_class_shadows (shadows)     tree shadows;{  class_binding_level->class_shadowed = shadows;}/* 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)    my_friendly_assert (named_labels == NULL_TREE, 134);  /* 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 ();    }  push_binding_level (newlevel, tag_transparent, keep_next_level_flag);  GNU_xref_start_scope ((HOST_WIDE_INT) newlevel);  keep_next_level_flag = 0;}voidnote_level_for_for (){  current_binding_level->is_for_scope = 1;}voidpushlevel_temporary (tag_transparent)     int tag_transparent;{  pushlevel (tag_transparent);  current_binding_level->keep = 2;  clear_last_expr ();  /* Note we don't call push_momentary() here.  Otherwise, it would cause     cleanups to be allocated on the momentary obstack, and they will be     overwritten by the next statement.  */  expand_start_bindings (0);}/* For a binding between a name and an entity at a block scope,   this is the `struct binding_level' for the block.  */#define BINDING_LEVEL(NODE) \   (((struct tree_binding*)NODE)->scope.level)/* These are currently unused, but permanent, CPLUS_BINDING nodes.   They are kept here because they are allocated from the permanent   obstack and cannot be easily freed.  */static tree free_binding_nodes;/* Make DECL the innermost binding for ID.  The LEVEL is the binding   level at which this declaration is being bound.  */static voidpush_binding (id, decl, level)     tree id;     tree decl;     struct binding_level* level;{  tree binding;  if (!free_binding_nodes)    {      /* There are no free nodes, so we must build one here.  */      push_obstacks_nochange ();      end_temporary_allocation ();      binding = make_node (CPLUS_BINDING);      pop_obstacks ();    }  else    {      /* There are nodes on the free list.  Grab the first one.  */      binding = free_binding_nodes;            /* And update the free list.  */      free_binding_nodes = TREE_CHAIN (free_binding_nodes);    }  /* Now, fill in the binding information.  */  BINDING_VALUE (binding) = decl;  BINDING_TYPE (binding) = NULL_TREE;  BINDING_LEVEL (binding) = level;  INHERITED_VALUE_BINDING_P (binding) = 0;  LOCAL_BINDING_P (binding) = (level != class_binding_level);  /* And put it on the front of the list of bindings for ID.  */  TREE_CHAIN (binding) = IDENTIFIER_BINDING (id);  IDENTIFIER_BINDING (id) = binding;}/* ID is already bound in the current scope.  But, DECL is an   additional binding for ID in the same scope.  This is the `struct   stat' hack whereby a non-typedef class-name or enum-name can be   bound at the same level as some other kind of entity.  It's the   responsibility of the caller to check that inserting this name is   legal here.  Returns nonzero if the new binding was successful.  */static intadd_binding (id, decl)     tree id;     tree decl;{  tree binding = IDENTIFIER_BINDING (id);  int ok = 1;  if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))    /* The new name is the type name.  */    BINDING_TYPE (binding) = decl;  else if (!BINDING_VALUE (binding))    /* This situation arises when push_class_level_binding moves an       inherited type-binding out of the way to make room for a new       value binding.  */    BINDING_VALUE (binding) = decl;  else if (TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL	   && DECL_ARTIFICIAL (BINDING_VALUE (binding)))    {      /* The old binding was a type name.  It was placed in	 BINDING_VALUE because it was thought, at the point it was	 declared, to be the only entity with such a name.  Move the	 type name into the type slot; it is now hidden by the new	 binding.  */      BINDING_TYPE (binding) = BINDING_VALUE (binding);      BINDING_VALUE (binding) = decl;      INHERITED_VALUE_BINDING_P (binding) = 0;    }  else    {      cp_error ("declaration of `%#D'", decl);      cp_error_at ("conflicts with previous declaration `%#D'",		   BINDING_VALUE (binding));      ok = 0;    }  return ok;}/* Bind DECL to ID in the current_binding_level.   If PUSH_USING is set in FLAGS, we know that DECL doesn't really belong   to this binding level, that it got here through a using-declaration.  */voidpush_local_binding (id, decl, flags)     tree id;     tree decl;     int flags;{  struct binding_level *b;  /* Skip over any local classes.  This makes sense if we call     push_local_binding with a friend decl of a local class.  */  b = current_binding_level;  while (b->parm_flag == 2)    b = b->level_chain;  if (lookup_name_current_level (id))    {      /* Supplement the existing binding.  */      if (!add_binding (id, decl))	/* It didn't work.  Something else must be bound at this	   level.  Do not add DECL to the list of things to pop	   later.  */	return;    }  else    /* Create a new binding.  */    push_binding (id, decl, b);  if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))    /* We must put the OVERLOAD into a TREE_LIST since the       TREE_CHAIN of an OVERLOAD is already used.  Similarly for       decls that got here through a using-declaration.  */    decl = build_tree_list (NULL_TREE, decl);  /* And put DECL on the list of things declared by the current     binding level.  */  TREE_CHAIN (decl) = b->names;  b->names = decl;}/* Bind DECL to ID in the class_binding_level.  Returns nonzero if the   binding was successful.  */intpush_class_binding (id, decl)     tree id;     tree decl;{  int result = 1;  tree binding = IDENTIFIER_BINDING (id);  tree context;  /* Note that we declared this value so that we can issue an error if     this an illegal redeclaration of a name already used for some     other purpose.  */  note_name_declared_in_class (id, decl);  if (binding && BINDING_LEVEL (binding) == class_binding_level)    /* Supplement the existing binding.  */    result = add_binding (id, decl);  else    /* Create a new binding.  */    push_binding (id, decl, class_binding_level);  /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the     class-level declaration.  Note that we do not use DECL here     because of the possibility of the `struct stat' hack; if DECL is     a class-name or enum-name we might prefer a field-name, or some     such.  */  IDENTIFIER_CLASS_VALUE (id) = BINDING_VALUE (IDENTIFIER_BINDING (id));  /* If this is a binding from a base class, mark it as such.  */  binding = IDENTIFIER_BINDING (id);  if (BINDING_VALUE (binding) == decl && TREE_CODE (decl) != TREE_LIST)    {      /* Any implicit typename must be from a base-class.  The	 context for an implicit typename declaration is always	 the derived class in which the lookup was done, so the checks	 based on the context of DECL below will not trigger.  */      if (TREE_CODE (decl) == TYPE_DECL 	  && IMPLICIT_TYPENAME_P (TREE_TYPE (decl)))	INHERITED_VALUE_BINDING_P (binding) = 1;      else	{	  if (TREE_CODE (decl) == OVERLOAD)	    context = DECL_REAL_CONTEXT (OVL_CURRENT (decl));	  else	    {	      my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd',				  0);	      context = DECL_REAL_CONTEXT (decl);	    }	  if (is_properly_derived_from (current_class_type, context))	    INHERITED_VALUE_BINDING_P (binding) = 1;	  else	    INHERITED_VALUE_BINDING_P (binding) = 0;	}    }  else if (BINDING_VALUE (binding) == decl)    /* We only encounter a TREE_LIST when push_class_decls detects an       ambiguity.  Such an ambiguity can be overridden by a definition       in this class.  */    INHERITED_VALUE_BINDING_P (binding) = 1;  return result;}/* Remove the binding for DECL which should be the innermost binding   for ID.  */static void pop_binding (id, decl)      tree id;     tree decl;{  tree binding;      if (id == NULL_TREE)    /* It's easiest to write the loops that call this function without       checking whether or not the entities involved have names.  We       get here for such an entity.  */    return;  /* Get the innermost binding for ID.  */  binding = IDENTIFIER_BINDING (id);  /* The name should be bound.  */  my_friendly_assert (binding != NULL_TREE, 0);  /* The DECL will be either the ordinary binding or the type     binding for this identifier.  Remove that binding.  */  if (BINDING_VALUE (binding) == decl)    BINDING_VALUE (binding) = NULL_TREE;  else if (BINDING_TYPE (binding) == decl)    BINDING_TYPE (binding) = NULL_TREE;  else    my_friendly_abort (0);  if (!BINDING_VALUE (binding) && !BINDING_TYPE (binding))    {      /* We're completely done with the innermost binding for this	 identifier.  Unhook it from the list of bindings.  */      IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);      /* And place it on the free list.  */      TREE_CHAIN (binding) = free_binding_nodes;      free_binding_nodes = binding;    }

⌨️ 快捷键说明

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