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

📄 cp-decl.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
print_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",	   lvl->n_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");  if (lvl->more_exceptions_ok)    fprintf (stderr, " more-exceptions-ok");  if (lvl->have_exceptions)    fprintf (stderr, " have-exceptions");  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 (TREE_CODE (t) == ERROR_MARK)	    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))        {#if 0          fprintf (stderr, "\n\t");          print_node_brief (stderr, "<", TREE_PURPOSE (t), 0);          if (TREE_VALUE (t))            print_node_brief (stderr, " ", TREE_VALUE (t), 0);          else            fprintf (stderr, " (none)");          fprintf (stderr, ">");#else	  fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));#endif        }      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);}/* 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, class_decl, function_decl;  struct binding_level *class_bindings;};static struct saved_scope *current_saved_scope;extern tree prev_class_type;voidpush_to_top_level (){  struct saved_scope *s =    (struct saved_scope *) xmalloc (sizeof (struct saved_scope));  struct binding_level *b = current_binding_level;  tree old_bindings = NULL_TREE;#ifdef DEBUG_CP_BINDING_LEVELS  fprintf (stderr, "PUSH_TO_TOP_LEVEL\n");#endif  /* Have to include global_binding_level, because class-level decls     aren't listed anywhere useful.  */  for (; b; b = b->level_chain)    {      tree t;      for (t = b->names; t; t = TREE_CHAIN (t))	if (b != global_binding_level)	  {	    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) = 0;		IDENTIFIER_CLASS_VALUE (id) = 0;		adjust_type_value (id);	      }	    TREE_CHAIN (binding) = old_bindings;	    old_bindings = binding;	    skip_it:	    ;	  }      /* Unwind type-value slots back to top level.  */      if (b != global_binding_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 = global_binding_level;  s->class_name = current_class_name;  s->class_type = current_class_type;  s->class_decl = current_class_decl;  s->function_decl = current_function_decl;  s->class_bindings = class_binding_level;  current_class_name = current_class_type = current_class_decl = 0;  current_function_decl = 0;  class_binding_level = 0;  s->prev = current_saved_scope;  s->old_bindings = old_bindings;  current_saved_scope = s;  binding_levels_sane();}voidpop_from_top_level (){  struct saved_scope *s = current_saved_scope;  tree t;#ifdef DEBUG_CP_BINDING_LEVELS  fprintf (stderr, "POP_FROM_TOP_LEVEL\n");#endif  binding_levels_sane();  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_class_decl = s->class_decl;  if (current_class_type)    C_C_D = CLASSTYPE_INST_VAR (current_class_type);  else    C_C_D = NULL_TREE;  current_function_decl = s->function_decl;  class_binding_level = s->class_bindings;  free (s);  binding_levels_sane();}/* Push a definition 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.   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.  */voidset_identifier_type_value (id, type)     tree id;     tree type;{  if (current_binding_level != global_binding_level)    {      tree old_type_value = IDENTIFIER_TYPE_VALUE (id);      current_binding_level->type_shadowed	= tree_cons (id, old_type_value, current_binding_level->type_shadowed);    }  else if (class_binding_level)    {      tree old_type_value = IDENTIFIER_TYPE_VALUE (id);      class_binding_level->type_shadowed	= tree_cons (id, old_type_value, class_binding_level->type_shadowed);    }        SET_IDENTIFIER_TYPE_VALUE (id, type);}/* * local values can need to be shadowed too, but it only happens * explicitly from pushdecl, in support of nested enums. */voidset_identifier_local_value (id, type)     tree id;     tree type;{  if (current_binding_level != global_binding_level)    {      tree old_local_value = IDENTIFIER_LOCAL_VALUE (id);      current_binding_level->shadowed	= tree_cons (id, old_local_value, current_binding_level->shadowed);    }  else if (class_binding_level)    {      tree old_local_value = IDENTIFIER_LOCAL_VALUE (id);      class_binding_level->shadowed	= tree_cons (id, old_local_value, class_binding_level->shadowed);    }        IDENTIFIER_LOCAL_VALUE (id) = type;}/* 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;{  my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 136);  if (classname != 0)    {      char *buf;      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);      SET_IDENTIFIER_TYPE_VALUE (DECL_NESTED_TYPENAME (decl), type);    }  else    DECL_NESTED_TYPENAME (decl) = name;}#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 cp-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    {      /* Typedef for unnamed struct; some other situations.	 TYPE_NAME is null; what's right here?  */    }  return decl;}#endifvoidpushtag (name, type)     tree name, type;{  register struct binding_level *b;  if (class_binding_level)    b = class_binding_level;  else    {      b = current_binding_level;      while (b->tag_transparent) b = b->level_chain;    }  if (b == global_binding_level)    b->tags = perm_tree_cons (name, type, b->tags);  else    b->tags = saveable_tree_cons (name, type, b->tags);  if (name)    {      /* Record the identifier as the type's name if it has none.  */      if (TYPE_NAME (type) == 0)        TYPE_NAME (type) = name;            /* Do C++ gratuitous typedefing.  */      if (IDENTIFIER_TYPE_VALUE (name) != type	  && (TREE_CODE (type) != RECORD_TYPE	      || class_binding_level == 0	      || !CLASSTYPE_DECLARED_EXCEPTION (type)))        {          register tree d;	  if (current_class_type == 0

⌨️ 快捷键说明

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