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

📄 pt.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
			 TREE_CODE (TREE_TYPE (TREE_TYPE (val))) == FUNCTION_TYPE			 ? "a function" : "an object");		  val = error_mark_node;		}	    }	}      if (val == error_mark_node)	lost++;      TREE_VEC_ELT (vec, i) = val;    }  if (lost)    return error_mark_node;  return vec;}/* Given class template name and parameter list, produce a user-friendly name   for the instantiation.  */static char *mangle_class_name_for_template (name, parms, arglist)     char *name;     tree parms, arglist;{  static struct obstack scratch_obstack;  static char *scratch_firstobj;  int i, nparms;  if (!scratch_firstobj)    {      gcc_obstack_init (&scratch_obstack);      scratch_firstobj = obstack_alloc (&scratch_obstack, 1);    }  else    obstack_free (&scratch_obstack, scratch_firstobj);#if 0#define buflen	sizeof(buf)#define check	if (bufp >= buf+buflen-1) goto too_long#define ccat(c) *bufp++=(c); check#define advance	bufp+=strlen(bufp); check#define cat(s)	strncpy(bufp, s, buf+buflen-bufp-1); advance#else#define check#define ccat(c)	obstack_1grow (&scratch_obstack, (c));#define advance#define cat(s)	obstack_grow (&scratch_obstack, (s), strlen (s))#endif  cat (name);  ccat ('<');  nparms = TREE_VEC_LENGTH (parms);  my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268);  for (i = 0; i < nparms; i++)    {      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));      tree arg = TREE_VEC_ELT (arglist, i);      if (i)	ccat (',');      if (TREE_CODE (parm) == TYPE_DECL)	{	  cat (type_as_string (arg, 0));	  continue;	}      else	my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269);      if (TREE_CODE (arg) == TREE_LIST)	{	  /* New list cell was built because old chain link was in	     use.  */	  my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270);	  arg = TREE_VALUE (arg);	}      /* No need to check arglist against parmlist here; we did that	 in coerce_template_parms, called from lookup_template_class.  */      cat (expr_as_string (arg, 0));    }  {    char *bufp = obstack_next_free (&scratch_obstack);    int offset = 0;    while (bufp[offset - 1] == ' ')      offset--;    obstack_blank_fast (&scratch_obstack, offset);    /* B<C<char> >, not B<C<char>> */    if (bufp[offset - 1] == '>')      ccat (' ');  }  ccat ('>');  ccat ('\0');  return (char *) obstack_base (&scratch_obstack);#if 0 too_long:#endif  fatal ("out of (preallocated) string space creating template instantiation name");  /* NOTREACHED */  return NULL;}/* Given an IDENTIFIER_NODE (type TEMPLATE_DECL) and a chain of   parameters, find the desired type.   D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.   Since ARGLIST is build on the decl_obstack, we must copy it here   to keep it from being reclaimed when the decl storage is reclaimed.   IN_DECL, if non-NULL, is the template declaration we are trying to   instantiate.  */treelookup_template_class (d1, arglist, in_decl)     tree d1, arglist;     tree in_decl;{  tree template, parmlist;  char *mangled_name;  tree id;  my_friendly_assert (TREE_CODE (d1) == IDENTIFIER_NODE, 272);  template = IDENTIFIER_GLOBAL_VALUE (d1); /* XXX */  if (! template)    template = IDENTIFIER_CLASS_VALUE (d1);  /* With something like `template <class T> class X class X { ... };'     we could end up with D1 having nothing but an IDENTIFIER_LOCAL_VALUE.     We don't want to do that, but we have to deal with the situation, so     let's give them some syntax errors to chew on instead of a crash.  */  if (! template)    return error_mark_node;  if (TREE_CODE (template) != TEMPLATE_DECL)    {      cp_error ("non-template type `%T' used as a template", d1);      if (in_decl)	cp_error_at ("for template declaration `%D'", in_decl);      return error_mark_node;    }  parmlist = DECL_TEMPLATE_PARMS (template);  arglist = coerce_template_parms (parmlist, arglist, template);  if (arglist == error_mark_node)    return error_mark_node;  if (uses_template_parms (arglist))    {      tree t = make_lang_type (UNINSTANTIATED_P_TYPE);      tree d;      id = make_anon_name ();      d = build_decl (TYPE_DECL, id, t);      TYPE_NAME (t) = d;      TYPE_VALUES (t) = build_tree_list (template, arglist);      pushdecl_top_level (d);    }  else    {      mangled_name = mangle_class_name_for_template (IDENTIFIER_POINTER (d1),						     parmlist, arglist);      id = get_identifier (mangled_name);    }  if (!IDENTIFIER_TEMPLATE (id))    {      arglist = copy_to_permanent (arglist);      IDENTIFIER_TEMPLATE (id) = perm_tree_cons (template, arglist, NULL_TREE);    }  return id;}voidpush_template_decls (parmlist, arglist, class_level)     tree parmlist, arglist;     int class_level;{  int i, nparms;  /* Don't want to push values into global context.  */  if (!class_level)    {      pushlevel (1);      declare_pseudo_global_level ();    }  nparms = TREE_VEC_LENGTH (parmlist);  for (i = 0; i < nparms; i++)    {      int requires_type, is_type;      tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));      tree arg = TREE_VEC_ELT (arglist, i);      tree decl = 0;      requires_type = TREE_CODE (parm) == TYPE_DECL;      is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't';      if (is_type)	{	  /* add typename to namespace */	  if (!requires_type)	    {	      error ("template use error: type provided where value needed");	      continue;	    }	  decl = arg;	  my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 't', 273);	  decl = build_decl (TYPE_DECL, DECL_NAME (parm), decl);	}      else	{	  /* add const decl to namespace */	  tree val;	  tree parmtype;	  if (requires_type)	    {	      error ("template use error: value provided where type needed");	      continue;	    }	  parmtype = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (arglist, 0),			     TREE_VEC_LENGTH (arglist), NULL_TREE);	  val = digest_init (parmtype, arg, (tree *) 0);	  if (val != error_mark_node)	    {	      decl = build_decl (CONST_DECL, DECL_NAME (parm),				 parmtype);	      DECL_INITIAL (decl) = val;	      TREE_READONLY (decl) = 1;	    }	}      if (decl != 0)	{	  SET_DECL_ARTIFICIAL (decl);	  layout_decl (decl, 0);	  if (class_level)	    pushdecl_class_level (decl);	  else	    pushdecl (decl);	}    }}voidpop_template_decls (parmlist, arglist, class_level)     tree parmlist, arglist;     int class_level;{  if (!class_level)    poplevel (0, 0, 0);}/* Should be defined in parse.h.  */extern int yychar;intuses_template_parms (t)     tree t;{  if (!t)    return 0;  switch (TREE_CODE (t))    {    case INDIRECT_REF:    case COMPONENT_REF:      /* We assume that the object must be instantiated in order to build	 the COMPONENT_REF, so we test only whether the type of the	 COMPONENT_REF uses template parms.  */      return uses_template_parms (TREE_TYPE (t));    case IDENTIFIER_NODE:      if (!IDENTIFIER_TEMPLATE (t))	return 0;      return uses_template_parms (TREE_VALUE (IDENTIFIER_TEMPLATE (t)));      /* aggregates of tree nodes */    case TREE_VEC:      {	int i = TREE_VEC_LENGTH (t);	while (i--)	  if (uses_template_parms (TREE_VEC_ELT (t, i)))	    return 1;	return 0;      }    case TREE_LIST:      if (uses_template_parms (TREE_PURPOSE (t))	  || uses_template_parms (TREE_VALUE (t)))	return 1;      return uses_template_parms (TREE_CHAIN (t));      /* constructed type nodes */    case POINTER_TYPE:    case REFERENCE_TYPE:      return uses_template_parms (TREE_TYPE (t));    case RECORD_TYPE:      if (TYPE_PTRMEMFUNC_FLAG (t))	return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (t));    case UNION_TYPE:      if (!TYPE_NAME (t))	return 0;      if (!TYPE_IDENTIFIER (t))	return 0;      return uses_template_parms (TYPE_IDENTIFIER (t));    case FUNCTION_TYPE:      if (uses_template_parms (TYPE_ARG_TYPES (t)))	return 1;      return uses_template_parms (TREE_TYPE (t));    case ARRAY_TYPE:      if (uses_template_parms (TYPE_DOMAIN (t)))	return 1;      return uses_template_parms (TREE_TYPE (t));    case OFFSET_TYPE:      if (uses_template_parms (TYPE_OFFSET_BASETYPE (t)))	return 1;      return uses_template_parms (TREE_TYPE (t));    case METHOD_TYPE:      if (uses_template_parms (TYPE_METHOD_BASETYPE (t)))	return 1;      if (uses_template_parms (TYPE_ARG_TYPES (t)))	return 1;      return uses_template_parms (TREE_TYPE (t));      /* decl nodes */    case TYPE_DECL:      return uses_template_parms (DECL_NAME (t));    case FUNCTION_DECL:      if (uses_template_parms (TREE_TYPE (t)))	return 1;      /* fall through */    case VAR_DECL:    case PARM_DECL:      /* ??? What about FIELD_DECLs?  */      /* The type of a decl can't use template parms if the name of the	 variable doesn't, because it's impossible to resolve them.  So	 ignore the type field for now.	 */      if (DECL_CONTEXT (t) && uses_template_parms (DECL_CONTEXT (t)))	return 1;      if (uses_template_parms (TREE_TYPE (t)))	{	  error ("template parms used where they can't be resolved");	}      return 0;    case CALL_EXPR:      return uses_template_parms (TREE_TYPE (t));    case ADDR_EXPR:      return uses_template_parms (TREE_OPERAND (t, 0));      /* template parm nodes */    case TEMPLATE_TYPE_PARM:    case TEMPLATE_CONST_PARM:      return 1;      /* simple type nodes */    case INTEGER_TYPE:      if (uses_template_parms (TYPE_MIN_VALUE (t)))	return 1;      return uses_template_parms (TYPE_MAX_VALUE (t));    case REAL_TYPE:    case VOID_TYPE:    case ENUMERAL_TYPE:    case BOOLEAN_TYPE:      return 0;      /* constants */    case INTEGER_CST:    case REAL_CST:    case STRING_CST:      return 0;    case ERROR_MARK:      /* Non-error_mark_node ERROR_MARKs are bad things.  */      my_friendly_assert (t == error_mark_node, 274);      /* NOTREACHED */      return 0;    case UNINSTANTIATED_P_TYPE:      return 1;    case CONSTRUCTOR:      if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))	return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));      /* else fall through */    default:      switch (TREE_CODE_CLASS (TREE_CODE (t)))	{	case '1':	case '2':	case '3':	case '<':	  {	    int i;	    for (i = tree_code_length[(int) TREE_CODE (t)]; --i >= 0;)	      if (uses_template_parms (TREE_OPERAND (t, i)))		return 1;	    return 0;	  }	default:	  break;	}      sorry ("testing %s for template parms",	     tree_code_name [(int) TREE_CODE (t)]);      my_friendly_abort (82);      /* NOTREACHED */      return 0;    }}voidinstantiate_member_templates (classname)     tree classname;{  tree t;  tree id = classname;  tree members = DECL_TEMPLATE_MEMBERS (TREE_PURPOSE (IDENTIFIER_TEMPLATE (id)));  for (t = members; t; t = TREE_CHAIN (t))    {      tree parmvec, type, classparms, tdecl, t2;      int nparms, xxx = 0, i;      my_friendly_assert (TREE_VALUE (t) != NULL_TREE, 275);      my_friendly_assert (TREE_CODE (TREE_VALUE (t)) == TEMPLATE_DECL, 276);      /* @@ Should verify that class parm list is a list of	 distinct template parameters, and covers all the template	 parameters.  */      tdecl = TREE_VALUE (t);      type = DECL_CONTEXT (DECL_TEMPLATE_RESULT (tdecl));      classparms = UPT_PARMS (type);      nparms = TREE_VEC_LENGTH (classparms);      parmvec = make_tree_vec (nparms);      for (i = 0; i < nparms; i++)	TREE_VEC_ELT (parmvec, i) = NULL_TREE;      switch (unify (DECL_TEMPLATE_PARMS (tdecl),		     &TREE_VEC_ELT (parmvec, 0), nparms,		     type, IDENTIFIER_TYPE_VALUE (classname),		     &xxx))	{	case 0:	  /* Success -- well, no inconsistency, at least.  */	  for (i = 0; i < nparms; i++)	    if (TREE_VEC_ELT (parmvec, i) == NULL_TREE)	      goto failure;	  t2 = instantiate_template (tdecl,				     &TREE_VEC_ELT (parmvec, 0));	  type = IDENTIFIER_TYPE_VALUE (id);	  my_friendly_assert (type != 0, 277);	  break;	case 1:	  /* Failure.  */	failure:	  cp_error_at ("type unification error instantiating `%D'", tdecl);	  cp_error ("while instantiating members of `%T'", classname);	  continue /* loop of members */;	default:	  /* Eek, a bug.  */	  my_friendly_abort (83);	}    }}static struct tinst_level *current_tinst_level = 0;

⌨️ 快捷键说明

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