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

📄 decl.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      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 ();#endif}/* 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;  struct binding_level *class_bindings;  tree *lang_base, *lang_stack, lang_name;  int lang_stacksize;  int minimal_parse_mode;  tree last_function_parms;  tree template_parms;  HOST_WIDE_INT processing_template_decl;  tree previous_class_type, previous_class_values;};static struct saved_scope *current_saved_scope;static treestore_bindings (names, old_bindings)     tree names, old_bindings;{  tree t;  for (t = names; t; t = TREE_CHAIN (t))    {      tree binding, t1, id;      if (TREE_CODE (t) == TREE_LIST)	id = TREE_PURPOSE (t);      else	id = DECL_NAME (t);      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:      ;    }  return old_bindings;}voidmaybe_push_to_top_level (pseudo)     int pseudo;{  extern int current_lang_stacksize;  struct saved_scope *s    = (struct saved_scope *) xmalloc (sizeof (struct saved_scope));  struct binding_level *b = inner_binding_level;  tree old_bindings = NULL_TREE;  if (current_function_decl)    push_cp_function_context (NULL_TREE);  if (previous_class_type)    old_bindings = store_bindings (previous_class_values, old_bindings);  /* 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 || (pseudo && b->pseudo_global))	break;      old_bindings = store_bindings (b->names, old_bindings);      /* We also need to check class_shadowed to save class-level type	 bindings, since pushclass doesn't fill in b->names.  */      if (b->parm_flag == 2)	old_bindings = store_bindings (b->class_shadowed, old_bindings);      /* 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));    }  s->old_binding_level = current_binding_level;  current_binding_level = b;  s->class_name = current_class_name;  s->class_type = current_class_type;  s->function_decl = current_function_decl;  s->class_bindings = class_binding_level;  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->minimal_parse_mode = minimal_parse_mode;  s->last_function_parms = last_function_parms;  s->template_parms = current_template_parms;  s->processing_template_decl = processing_template_decl;  s->previous_class_type = previous_class_type;  s->previous_class_values = previous_class_values;  current_class_name = current_class_type = NULL_TREE;  current_function_decl = NULL_TREE;  class_binding_level = (struct binding_level *)0;  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;  minimal_parse_mode = 0;  previous_class_type = previous_class_values = NULL_TREE;  if (!pseudo)    {      current_template_parms = NULL_TREE;      processing_template_decl = 0;    }  s->prev = current_saved_scope;  s->old_bindings = old_bindings;  current_saved_scope = s;  push_obstacks (&permanent_obstack, &permanent_obstack);}voidpush_to_top_level (){  maybe_push_to_top_level (0);}voidpop_from_top_level (){  extern int current_lang_stacksize;  struct saved_scope *s = current_saved_scope;  tree t;  /* Clear out class-level bindings cache.  */  if (previous_class_type)    {      popclass (-1);      previous_class_type = NULL_TREE;    }  pop_obstacks ();  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_function_decl = s->function_decl;  class_binding_level = s->class_bindings;  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;  minimal_parse_mode = s->minimal_parse_mode;  last_function_parms = s->last_function_parms;  current_template_parms = s->template_parms;  processing_template_decl = s->processing_template_decl;  previous_class_type = s->previous_class_type;  previous_class_values = s->previous_class_values;  free (s);  if (current_function_decl)    pop_cp_function_context (NULL_TREE);}/* 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);}/* 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}/* 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);      /* 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;		  d = build_decl (TYPE_DECL, name, type);		  SET_DECL_ARTIFICIAL (d);		  set_identifier_type_value_with_scope (name, type, b);		}	      else		d = TYPE_MAIN_DECL (d);	      TYPE_NAME (type) = d;	      DECL_CONTEXT (d) = context;	      if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))		push_template_decl (d);	      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);	      TYPE_NAME (type) = d;	      DECL_CONTEXT (d) = context;	      if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))		push_template_decl (d);	      d = pushdecl_class_level (d);	    }	  if (newdecl)	    {	      if (ANON_AGGRNAME_P (name))		DECL_IGNORED_P (d) = 1;	      TYPE_CONTEXT (type) = DECL_CONTEXT (d);	      DECL_ASSEMBLER_NAME (d) = DECL_NAME (d);	      DECL_ASSEMBLER_NAME (d)		= get_identifier (build_overload_name (type, 1, 1));	    }        }      if (b->parm_flag == 2)	{	  TREE_NONLOCAL_FLAG (type) = 1;	  if (TYPE_SIZE (current_class_type) == NULL_TREE)	    CLASSTYPE_TAGS (current_class_type) = b->tags;	}    }  if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)    /* Use the canonical TYPE_DECL for this node.  */    TYPE_STUB_DECL (type) = TYPE_NAME (type);  else    {      /* 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.  */      tree d = build_decl (TYPE_DECL, NULL_TREE, type);      TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);    }}/* Counter used to create anonymous type names.  */static int anon_cnt = 0;/* Return an IDENTIFIER which can be used as a name for   anonymous structs and unions.  */treemake_anon_name (){  char buf[32];  sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++);  return get_identifier (buf);}/* Clear the TREE_PURPOSE slot of tags which have anonymous typenames.   This keeps dbxout from getting confused.  */voidclear_anon_tags (){  register struct binding_level *b;  register tree tags;  static int last_cnt = 0;  /* Fast out if no new anon names were declared.  */  if (last_cnt == anon_cnt)    return;  b = current_binding_level;  while (b->tag_transparent)    b = b->level_chain;  tags = b->tags;  while (tags)    {      /* A NULL purpose means we have already processed all tags	 from here to the end 

⌨️ 快捷键说明

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