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

📄 decl.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* 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))    {      if (DECL_NAME (link) != NULL_TREE)	{	  /* 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_ASSEMBLER_NAME (link)) = 1;	      if (TREE_ADDRESSABLE (link))		TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;	    }	  IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE;	}    }  /* 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);  for (link = current_binding_level->class_shadowed;       link; link = TREE_CHAIN (link))    IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);  for (link = current_binding_level->type_shadowed;       link; link = TREE_CHAIN (link))    IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);  /* suspend a level.  */  suspend_binding_level ();}/* Subroutines for reverting temporarily to top-level for instantiation   of templates and such.  We actually need to clear out the class- and   local-value slots of all identifiers, so that only the global values   are at all visible.  Simply setting current_binding_level to the global   scope isn't enough, because more binding levels may be pushed.  */struct saved_scope {  struct binding_level *old_binding_level;  tree old_bindings;  struct saved_scope *prev;  tree class_name, class_type, function_decl;  tree base_init_list, member_init_list;  struct binding_level *class_bindings;  tree previous_class_type;  tree *lang_base, *lang_stack, lang_name;  int lang_stacksize;  tree named_labels;};static struct saved_scope *current_saved_scope;extern tree prev_class_type;voidpush_to_top_level (){  extern int current_lang_stacksize;  struct saved_scope *s =    (struct saved_scope *) xmalloc (sizeof (struct saved_scope));  struct binding_level *b = current_binding_level;  tree old_bindings = NULL_TREE;  /* Have to include global_binding_level, because class-level decls     aren't listed anywhere useful.  */  for (; b; b = b->level_chain)    {      tree t;      if (b == global_binding_level)	continue;            for (t = b->names; t; t = TREE_CHAIN (t))	{	  tree binding, t1, t2 = t;	  tree id = DECL_ASSEMBLER_NAME (t2);	  if (!id	      || (!IDENTIFIER_LOCAL_VALUE (id)		  && !IDENTIFIER_CLASS_VALUE (id)))	    continue;	  for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1))	    if (TREE_VEC_ELT (t1, 0) == id)	      goto skip_it;	    	  binding = make_tree_vec (4);	  if (id)	    {	      my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);	      TREE_VEC_ELT (binding, 0) = id;	      TREE_VEC_ELT (binding, 1) = IDENTIFIER_TYPE_VALUE (id);	      TREE_VEC_ELT (binding, 2) = IDENTIFIER_LOCAL_VALUE (id);	      TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);	      IDENTIFIER_LOCAL_VALUE (id) = NULL_TREE;	      IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;	    }	  TREE_CHAIN (binding) = old_bindings;	  old_bindings = binding;	skip_it:	  ;	}      /* Unwind type-value slots back to top level.  */      for (t = b->type_shadowed; t; t = TREE_CHAIN (t))	SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));    }  /* Clear out class-level bindings cache.  */  if (current_binding_level == global_binding_level      && previous_class_type != NULL_TREE)    {      popclass (-1);      previous_class_type = NULL_TREE;    }  s->old_binding_level = current_binding_level;  current_binding_level = global_binding_level;  s->class_name = current_class_name;  s->class_type = current_class_type;  s->function_decl = current_function_decl;  s->base_init_list = current_base_init_list;  s->member_init_list = current_member_init_list;  s->class_bindings = class_binding_level;  s->previous_class_type = previous_class_type;  s->lang_stack = current_lang_stack;  s->lang_base = current_lang_base;  s->lang_stacksize = current_lang_stacksize;  s->lang_name = current_lang_name;  s->named_labels = named_labels;  current_class_name = current_class_type = NULL_TREE;  current_function_decl = NULL_TREE;  class_binding_level = (struct binding_level *)0;  previous_class_type = NULL_TREE;  current_lang_stacksize = 10;  current_lang_stack = current_lang_base    = (tree *) xmalloc (current_lang_stacksize * sizeof (tree));  current_lang_name = lang_name_cplusplus;  strict_prototype = strict_prototypes_lang_cplusplus;  named_labels = NULL_TREE;  s->prev = current_saved_scope;  s->old_bindings = old_bindings;  current_saved_scope = s;}voidpop_from_top_level (){  extern int current_lang_stacksize;  struct saved_scope *s = current_saved_scope;  tree t;  if (previous_class_type)    previous_class_type = NULL_TREE;  current_binding_level = s->old_binding_level;  current_saved_scope = s->prev;  for (t = s->old_bindings; t; t = TREE_CHAIN (t))    {      tree id = TREE_VEC_ELT (t, 0);      if (id)	{	  IDENTIFIER_TYPE_VALUE (id) = TREE_VEC_ELT (t, 1);	  IDENTIFIER_LOCAL_VALUE (id) = TREE_VEC_ELT (t, 2);	  IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);	}    }  current_class_name = s->class_name;  current_class_type = s->class_type;  current_base_init_list = s->base_init_list;  current_member_init_list = s->member_init_list;  current_function_decl = s->function_decl;  class_binding_level = s->class_bindings;  previous_class_type = s->previous_class_type;  free (current_lang_base);  current_lang_base = s->lang_base;  current_lang_stack = s->lang_stack;  current_lang_name = s->lang_name;  current_lang_stacksize = s->lang_stacksize;  if (current_lang_name == lang_name_cplusplus)    strict_prototype = strict_prototypes_lang_cplusplus;  else if (current_lang_name == lang_name_c)    strict_prototype = strict_prototypes_lang_c;  named_labels = s->named_labels;  free (s);}/* Push a definition of struct, union or enum tag "name".   into binding_level "b".   "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 a NULL_TREE.   C++ gratuitously puts all these tags in the name space. *//* When setting the IDENTIFIER_TYPE_VALUE field of an identifier ID,   record the shadowed value for this binding contour.  TYPE is   the type that ID maps to.  */static voidset_identifier_type_value_with_scope (id, type, b)     tree id;     tree type;     struct binding_level *b;{  if (b != global_binding_level)    {      tree old_type_value = IDENTIFIER_TYPE_VALUE (id);      b->type_shadowed	= tree_cons (id, old_type_value, b->type_shadowed);    }  SET_IDENTIFIER_TYPE_VALUE (id, type);}/* As set_identifier_type_value_with_scope, but using inner_binding_level. */voidset_identifier_type_value (id, type)     tree id;     tree type;{  set_identifier_type_value_with_scope (id, type, inner_binding_level);}/* Subroutine "set_nested_typename" builds the nested-typename of   the type decl in question.  (Argument CLASSNAME can actually be   a function as well, if that's the smallest containing scope.)  */static voidset_nested_typename (decl, classname, name, type)     tree decl, classname, name, type;{  char *buf;  my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 136);  /* No need to do this for anonymous names, since they're unique.  */  if (ANON_AGGRNAME_P (name))    {      DECL_NESTED_TYPENAME (decl) = name;      return;    }  if (classname == NULL_TREE)    classname = get_identifier ("");  my_friendly_assert (TREE_CODE (classname) == IDENTIFIER_NODE, 137);  my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 138);  buf = (char *) alloca (4 + IDENTIFIER_LENGTH (classname)			 + IDENTIFIER_LENGTH (name));  sprintf (buf, "%s::%s", IDENTIFIER_POINTER (classname),	   IDENTIFIER_POINTER (name));  DECL_NESTED_TYPENAME (decl) = get_identifier (buf);  TREE_MANGLED (DECL_NESTED_TYPENAME (decl)) = 1;  /* Create an extra decl so that the nested name will have a type value     where appropriate.  */  {    tree nested, type_decl;    nested = DECL_NESTED_TYPENAME (decl);    type_decl = build_decl (TYPE_DECL, nested, type);    DECL_NESTED_TYPENAME (type_decl) = nested;    SET_DECL_ARTIFICIAL (type_decl);    /* Mark the TYPE_DECL node created just above as a gratuitous one so that       dwarfout.c will know not to generate a TAG_typedef DIE for it, and       sdbout.c won't try to output a .def for "::foo".  */    DECL_IGNORED_P (type_decl) = 1;    /* Remove this when local classes are fixed.  */    SET_IDENTIFIER_TYPE_VALUE (nested, type);    pushdecl_nonclass_level (type_decl);  }}/* Pop off extraneous binding levels left over due to syntax errors.   We don't pop past namespaces, as they might be valid.  */voidpop_everything (){#ifdef DEBUG_CP_BINDING_LEVELS  fprintf (stderr, "XXX entering pop_everything ()\n");#endif  while (! toplevel_bindings_p () && ! pseudo_global_level_p ())    {      if (class_binding_level)	pop_nested_class (1);      else	poplevel (0, 0, 0);    }#ifdef DEBUG_CP_BINDING_LEVELS  fprintf (stderr, "XXX leaving pop_everything ()\n");#endif}#if 0 /* not yet, should get fixed properly later *//* Create a TYPE_DECL node with the correct DECL_ASSEMBLER_NAME.   Other routines shouldn't use build_decl directly; they'll produce   incorrect results with `-g' unless they duplicate this code.   This is currently needed mainly for dbxout.c, but we can make   use of it in method.c later as well.  */treemake_type_decl (name, type)     tree name, type;{  tree decl, id;  decl = build_decl (TYPE_DECL, name, type);  if (TYPE_NAME (type) == name)    /* Class/union/enum definition, or a redundant typedef for same.  */    {      id = get_identifier (build_overload_name (type, 1, 1));      DECL_ASSEMBLER_NAME (decl) = id;    }  else if (TYPE_NAME (type) != NULL_TREE)    /* Explicit typedef, or implicit typedef for template expansion.  */    DECL_ASSEMBLER_NAME (decl) = DECL_ASSEMBLER_NAME (TYPE_NAME (type));  else    {      /* XXX: Typedef for unnamed struct; some other situations.	 TYPE_NAME is null; what's right here?  */    }  return decl;}#endif/* Push a tag name NAME for struct/class/union/enum type TYPE.   Normally put into into the inner-most non-tag-transparent scope,   but if GLOBALIZE is true, put it in the inner-most non-class scope.   The latter is needed for implicit declarations. */voidpushtag (name, type, globalize)     tree name, type;     int globalize;{  register struct binding_level *b;  tree context = 0;  tree c_decl = 0;  b = inner_binding_level;  while (b->tag_transparent	 || (globalize && b->parm_flag == 2))    b = b->level_chain;  if (toplevel_bindings_p ())    b->tags = perm_tree_cons (name, type, b->tags);  else    b->tags = saveable_tree_cons (name, type, b->tags);  if (name)    {      context = type ? TYPE_CONTEXT (type) : NULL_TREE;      if (! context && ! globalize)        context = current_scope ();      if (context)	c_decl = TREE_CODE (context) == FUNCTION_DECL	  ? context : TYPE_MAIN_DECL (context);#if 0      /* Record the identifier as the type's name if it has none.  */      if (TYPE_NAME (type) == NULL_TREE)        TYPE_NAME (type) = name;#endif            /* Do C++ gratuitous typedefing.  */      if (IDENTIFIER_TYPE_VALUE (name) != type)        {          register tree d;	  int newdecl = 0;	  	  if (b->parm_flag != 2	      || TYPE_SIZE (current_class_type) != NULL_TREE)	    {	      d = lookup_nested_type (type, c_decl);	      if (d == NULL_TREE)		{		  newdecl = 1;#if 0 /* not yet, should get fixed properly later */		  d = make_type_decl (name, type);#else		  d = build_decl (TYPE_DECL, name, type);		  DECL_ASSEMBLER_NAME (d) = current_namespace_id (DECL_ASSEMBLER_NAME (d));#endif		  SET_DECL_ARTIFICIAL (d);#ifdef DWARF_DEBUGGING_INFO		  if (write_symbols == DWARF_DEBUG)		    {		      /* Mark the TYPE_DECL node we created just above as an			 gratuitous one.  We need to do this so that dwarfout.c			 will understand that it is not supposed to output a			 TAG_typedef DIE  for it. */		      DECL_IGNORED_P (d) = 1;		    }#endif /* DWARF_DEBUGGING_INFO */		  set_identifier_type_value_with_scope (name, type, b);		}	      else		d = TYPE_NAME (d);	      TYPE_NAME (type) = d;	      /* If it is anonymous, then we are called from pushdecl,		 and we don't want to infinitely recurse.  */	      if (! ANON_AGGRNAME_P (name))		{		  if (b->parm_flag == 2)		    d = pushdecl_class_level (d);		  else		    d = pushdecl_with_scope (d, b);		}	    }	  else	    {	      /* Make nested declarations go into class-level scope.  */	      newdecl = 1;	      d = build_decl (TYPE_DECL, name, type);	      SET_DECL_ARTIFICIAL (d);#ifdef DWARF_DEBUGGING_INFO	      if (write_symbols == DWARF_DEBUG)		{		  /* Mark the TYPE_DECL node we created just above as an		     gratuitous one.  We need to do this so that dwarfout.c		     will understand that it is not supposed to 

⌨️ 快捷键说明

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