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

📄 pt.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
		      type);      tree t	= build_template_parm_index (TEMPLATE_PARM_IDX (index),				     TEMPLATE_PARM_LEVEL (index) - levels,				     TEMPLATE_PARM_ORIG_LEVEL (index),				     decl, type);      TEMPLATE_PARM_DESCENDANTS (index) = t;      /* Template template parameters need this.  */      DECL_TEMPLATE_PARMS (decl)	= DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));    }  return TEMPLATE_PARM_DESCENDANTS (index);}/* Process information from new template parameter NEXT and append it to the   LIST being built.  */treeprocess_template_parm (list, next)     tree list, next;{  tree parm;  tree decl = 0;  tree defval;  int is_type, idx;  parm = next;  my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);  defval = TREE_PURPOSE (parm);  parm = TREE_VALUE (parm);  is_type = TREE_PURPOSE (parm) == class_type_node;  if (list)    {      tree p = TREE_VALUE (tree_last (list));      if (TREE_CODE (p) == TYPE_DECL)	idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));      else if (TREE_CODE (p) == TEMPLATE_DECL)	idx = TEMPLATE_TYPE_IDX (TREE_TYPE (DECL_TEMPLATE_RESULT (p)));      else	idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p));      ++idx;    }  else    idx = 0;  if (!is_type)    {      my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);      /* is a const-param */      parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),			     PARM, 0, NULL_TREE);      /* [temp.param]	 The top-level cv-qualifiers on the template-parameter are	 ignored when determining its type.  */      TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));      /* A template parameter is not modifiable.  */      TREE_READONLY (parm) = 1;      if (IS_AGGR_TYPE (TREE_TYPE (parm))	  && TREE_CODE (TREE_TYPE (parm)) != TEMPLATE_TYPE_PARM	  && TREE_CODE (TREE_TYPE (parm)) != TYPENAME_TYPE)	{	  cp_error ("`%#T' is not a valid type for a template constant parameter",		    TREE_TYPE (parm));	  if (DECL_NAME (parm) == NULL_TREE)	    error ("  a template type parameter must begin with `class' or `typename'");	  TREE_TYPE (parm) = void_type_node;	}      else if (pedantic	       && (TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE		   || TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE))	cp_pedwarn ("`%T' is not a valid type for a template constant parameter",		    TREE_TYPE (parm));      if (TREE_PERMANENT (parm) == 0)        {	  parm = copy_node (parm);	  TREE_PERMANENT (parm) = 1;        }      decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));      DECL_INITIAL (parm) = DECL_INITIAL (decl) 	= build_template_parm_index (idx, processing_template_decl,				     processing_template_decl,				     decl, TREE_TYPE (parm));    }  else    {      tree t;      parm = TREE_VALUE (parm);            if (parm && TREE_CODE (parm) == TEMPLATE_DECL)	{	  t = make_lang_type (TEMPLATE_TEMPLATE_PARM);	  /* This is for distinguishing between real templates and template 	     template parameters */	  TREE_TYPE (parm) = t;	  TREE_TYPE (DECL_TEMPLATE_RESULT (parm)) = t;	  decl = parm;	}      else	{	  t = make_lang_type (TEMPLATE_TYPE_PARM);	  /* parm is either IDENTIFIER_NODE or NULL_TREE */	  decl = build_decl (TYPE_DECL, parm, t);	}              TYPE_NAME (t) = decl;      TYPE_STUB_DECL (t) = decl;      parm = decl;      TEMPLATE_TYPE_PARM_INDEX (t)	= build_template_parm_index (idx, processing_template_decl, 				     processing_template_decl,				     decl, TREE_TYPE (parm));    }  SET_DECL_ARTIFICIAL (decl);  DECL_TEMPLATE_PARM_P (decl) = 1;  pushdecl (decl);  parm = build_tree_list (defval, parm);  return chainon (list, parm);}/* The end of a template parameter list has been reached.  Process the   tree list into a parameter vector, converting each parameter into a more   useful form.	 Type parameters are saved as IDENTIFIER_NODEs, and others   as PARM_DECLs.  */treeend_template_parm_list (parms)     tree parms;{  int nparms;  tree parm;  tree saved_parmlist = make_tree_vec (list_length (parms));  current_template_parms    = tree_cons (build_int_2 (0, processing_template_decl),		 saved_parmlist, current_template_parms);  for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++)    TREE_VEC_ELT (saved_parmlist, nparms) = parm;  --processing_template_parmlist;  return saved_parmlist;}/* end_template_decl is called after a template declaration is seen.  */voidend_template_decl (){  reset_specialization ();  if (! processing_template_decl)    return;  /* This matches the pushlevel in begin_template_parm_list.  */  poplevel (0, 0, 0);  --processing_template_decl;  current_template_parms = TREE_CHAIN (current_template_parms);  (void) get_pending_sizes ();	/* Why? */}/* Given a template argument vector containing the template PARMS.   The innermost PARMS are given first.  */treecurrent_template_args (){  tree header;  tree args = NULL_TREE;  int length = TMPL_PARMS_DEPTH (current_template_parms);  int l = length;  /* If there is only one level of template parameters, we do not     create a TREE_VEC of TREE_VECs.  Instead, we return a single     TREE_VEC containing the arguments.  */  if (length > 1)    args = make_tree_vec (length);  for (header = current_template_parms; header; header = TREE_CHAIN (header))    {      tree a = copy_node (TREE_VALUE (header));      int i;      TREE_TYPE (a) = NULL_TREE;      for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i)	{	  tree t = TREE_VEC_ELT (a, i);	  /* T will be a list if we are called from within a	     begin/end_template_parm_list pair, but a vector directly	     if within a begin/end_member_template_processing pair.  */	  if (TREE_CODE (t) == TREE_LIST) 	    {	      t = TREE_VALUE (t);	      	      if (TREE_CODE (t) == TYPE_DECL 		  || TREE_CODE (t) == TEMPLATE_DECL)		t = TREE_TYPE (t);	      else		t = DECL_INITIAL (t);	      TREE_VEC_ELT (a, i) = t;	    }	}      if (length > 1)	TREE_VEC_ELT (args, --l) = a;      else	args = a;    }  return args;}/* Return a TEMPLATE_DECL corresponding to DECL, using the indicated   template PARMS.  Used by push_template_decl below.  */static treebuild_template_decl (decl, parms)     tree decl;     tree parms;{  tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);  DECL_TEMPLATE_PARMS (tmpl) = parms;  DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);  if (DECL_LANG_SPECIFIC (decl))    {      DECL_CLASS_CONTEXT (tmpl) = DECL_CLASS_CONTEXT (decl);      DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl);      DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl);    }  return tmpl;}struct template_parm_data{  /* The level of the template parameters we are currently     processing.  */  int level;  /* The index of the specialization argument we are currently     processing.  */  int current_arg;  /* An array whose size is the number of template parameters.  The     elements are non-zero if the parameter has been used in any one     of the arguments processed so far.  */  int* parms;  /* An array whose size is the number of template arguments.  The     elements are non-zero if the argument makes use of template     parameters of this level.  */  int* arg_uses_template_parms;};/* Subroutine of push_template_decl used to see if each template   parameter in a partial specialization is used in the explicit   argument list.  If T is of the LEVEL given in DATA (which is   treated as a template_parm_data*), then DATA->PARMS is marked   appropriately.  */static intmark_template_parm (t, data)     tree t;     void* data;{  int level;  int idx;  struct template_parm_data* tpd = (struct template_parm_data*) data;  if (TREE_CODE (t) == TEMPLATE_PARM_INDEX)    {      level = TEMPLATE_PARM_LEVEL (t);      idx = TEMPLATE_PARM_IDX (t);    }  else    {      level = TEMPLATE_TYPE_LEVEL (t);      idx = TEMPLATE_TYPE_IDX (t);    }  if (level == tpd->level)    {      tpd->parms[idx] = 1;      tpd->arg_uses_template_parms[tpd->current_arg] = 1;    }  /* Return zero so that for_each_template_parm will continue the     traversal of the tree; we want to mark *every* template parm.  */  return 0;}/* Process the partial specialization DECL.  */static treeprocess_partial_specialization (decl)     tree decl;{  tree type = TREE_TYPE (decl);  tree maintmpl = CLASSTYPE_TI_TEMPLATE (type);  tree specargs = CLASSTYPE_TI_ARGS (type);  tree inner_args = innermost_args (specargs);  tree inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);  tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl);  int nargs = TREE_VEC_LENGTH (inner_args);  int ntparms = TREE_VEC_LENGTH (inner_parms);  int  i;  int did_error_intro = 0;  struct template_parm_data tpd;  struct template_parm_data tpd2;  /* We check that each of the template parameters given in the     partial specialization is used in the argument list to the     specialization.  For example:       template <class T> struct S;       template <class T> struct S<T*>;     The second declaration is OK because `T*' uses the template     parameter T, whereas       template <class T> struct S<int>;     is no good.  Even trickier is:       template <class T>       struct S1       {	  template <class U>	  struct S2;	  template <class U>	  struct S2<T>;       };     The S2<T> declaration is actually illegal; it is a     full-specialization.  Of course, 	  template <class U>	  struct S2<T (*)(U)>;     or some such would have been OK.  */  tpd.level = TMPL_PARMS_DEPTH (current_template_parms);  tpd.parms = alloca (sizeof (int) * ntparms);  bzero ((PTR) tpd.parms, sizeof (int) * ntparms);  tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs);  bzero ((PTR) tpd.arg_uses_template_parms, sizeof (int) * nargs);  for (i = 0; i < nargs; ++i)    {      tpd.current_arg = i;      for_each_template_parm (TREE_VEC_ELT (inner_args, i),			      &mark_template_parm,			      &tpd);    }  for (i = 0; i < ntparms; ++i)    if (tpd.parms[i] == 0)      {	/* One of the template parms was not used in the           specialization.  */	if (!did_error_intro)	  {	    cp_error ("template parameters not used in partial specialization:");	    did_error_intro = 1;	  }	cp_error ("        `%D'", 		  TREE_VALUE (TREE_VEC_ELT (inner_parms, i)));      }  /* [temp.class.spec]     The argument list of the specialization shall not be identical to     the implicit argument list of the primary template.  */  if (comp_template_args (inner_args, 			  innermost_args (CLASSTYPE_TI_ARGS (TREE_TYPE							     (maintmpl)))))    cp_error ("partial specialization `%T' does not specialize any template arguments", type);  /* [temp.class.spec]     A partially specialized non-type argument expression shall not     involve template parameters of the partial specialization except     when the argument expression is a simple identifier.     The type of a template parameter corresponding to a specialized     non-type argument shall not be dependent on a parameter of the     specialization.  */  my_friendly_assert (nargs == DECL_NTPARMS (maintmpl), 0);  tpd2.parms = 0;  for (i = 0; i < nargs; ++i)    {      tree arg = TREE_VEC_ELT (inner_args, i);      if (/* These first two lines are the `non-type' bit.  */	  TREE_CODE_CLASS (TREE_CODE (arg)) != 't'	  && TREE_CODE (arg) != TEMPLATE_DECL	  /* This next line is the `argument expression is not just a	     simple identifier' condition and also the `specialized	     non-type argument' bit.  */	  && TREE_CODE (arg) != TEMPLATE_PARM_INDEX)	{	  if (tpd.arg_uses_template_parms[i])	    cp_error ("template argument `%E' involves template parameter(s)", arg);	  else 	    {	      /* Look at the corresponding template parameter,		 marking which template parameters its type depends		 upon.  */	      tree type = 		TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (main_inner_parms, 						     i)));	      if (!tpd2.parms)		{		  /* We haven't yet initialized TPD2.  Do so now.  */		  tpd2.arg_uses_template_parms 		    =  (int*) alloca (sizeof (int) * nargs);		  /* The number of parameters here is the number in the		     m

⌨️ 快捷键说明

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