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

📄 pt.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
	}    }  if (specialization || member_specialization)    {      tree t = TYPE_ARG_TYPES (TREE_TYPE (decl));      for (; t; t = TREE_CHAIN (t))	if (TREE_PURPOSE (t))	  {	    cp_pedwarn	      ("default argument specified in explicit specialization");	    break;	  }      if (current_lang_name == lang_name_c)	cp_error ("template specialization with C linkage");    }  if (specialization || member_specialization || explicit_instantiation)    {      tree tmpl = NULL_TREE;      tree targs = NULL_TREE;      /* Make sure that the declarator is a TEMPLATE_ID_EXPR.  */      if (TREE_CODE (declarator) != TEMPLATE_ID_EXPR)	{	  tree fns;	  my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE, 			      0);	  if (!ctype)	    fns = IDENTIFIER_NAMESPACE_VALUE (dname);	  else	    fns = dname;	  declarator = 	    lookup_template_function (fns, NULL_TREE);	}      if (declarator == error_mark_node)	return error_mark_node;      if (ctype != NULL_TREE && TYPE_BEING_DEFINED (ctype))	{	  if (!explicit_instantiation)	    /* A specialization in class scope.  This is illegal,	       but the error will already have been flagged by	       check_specialization_scope.  */	    return error_mark_node;	  else	    {	      /* It's not legal to write an explicit instantiation in		 class scope, e.g.:	           class C { template void f(); }		   This case is caught by the parser.  However, on		   something like:	       		   template class C { void f(); };		   (which is illegal) we can get here.  The error will be		   issued later.  */	      ;	    }	  return decl;	}      else if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR)	{	  /* A friend declaration.  We can't do much, because we don't	   know what this resolves to, yet.  */	  my_friendly_assert (is_friend != 0, 0);	  my_friendly_assert (!explicit_instantiation, 0);	  SET_DECL_IMPLICIT_INSTANTIATION (decl);	  return decl;	}       else if (ctype != NULL_TREE 	       && (TREE_CODE (TREE_OPERAND (declarator, 0)) ==		   IDENTIFIER_NODE))	{	  /* Find the list of functions in ctype that have the same	     name as the declared function.  */	  tree name = TREE_OPERAND (declarator, 0);	  tree fns = NULL_TREE;	  int idx;	  if (name == constructor_name (ctype) 	      || name == constructor_name_full (ctype))	    {	      int is_constructor = DECL_CONSTRUCTOR_P (decl);	      	      if (is_constructor ? !TYPE_HAS_CONSTRUCTOR (ctype)		  : !TYPE_HAS_DESTRUCTOR (ctype))		{		  /* From [temp.expl.spec]:		       		     If such an explicit specialization for the member		     of a class template names an implicitly-declared		     special member function (clause _special_), the		     program is ill-formed.  		     Similar language is found in [temp.explicit].  */		  cp_error ("specialization of implicitly-declared special member function");		  return error_mark_node;		}	      name = is_constructor ? ctor_identifier : dtor_identifier;	    }	  if (!IDENTIFIER_TYPENAME_P (name))	    {	      idx = lookup_fnfields_1 (ctype, name);	      if (idx >= 0)		fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), idx);	    }	  else	    {	      tree methods;	      /* For a type-conversion operator, we cannot do a		 name-based lookup.  We might be looking for `operator		 int' which will be a specialization of `operator T'.		 So, we find *all* the conversion operators, and then		 select from them.  */	      fns = NULL_TREE;	      methods = CLASSTYPE_METHOD_VEC (ctype);	      if (methods)		for (idx = 2; idx < TREE_VEC_LENGTH (methods); ++idx) 		  {		    tree ovl = TREE_VEC_ELT (methods, idx);		    if (!ovl || !DECL_CONV_FN_P (OVL_CURRENT (ovl)))		      /* There are no more conversion functions.  */		      break;		    /* Glue all these conversion functions together		       with those we already have.  */		    for (; ovl; ovl = OVL_NEXT (ovl))		      fns = ovl_cons (OVL_CURRENT (ovl), fns);		  }	    }	      	  if (fns == NULL_TREE) 	    {	      cp_error ("no member function `%D' declared in `%T'",			name, ctype);	      return error_mark_node;	    }	  else	    TREE_OPERAND (declarator, 0) = fns;	}            /* Figure out what exactly is being specialized at this point.	 Note that for an explicit instantiation, even one for a	 member function, we cannot tell apriori whether the	 instantiation is for a member template, or just a member	 function of a template class.  Even if a member template is	 being instantiated, the member template arguments may be	 elided if they can be deduced from the rest of the	 declaration.  */      tmpl = determine_specialization (declarator, decl,				       &targs, 				       member_specialization);	          if (!tmpl || tmpl == error_mark_node)	/* We couldn't figure out what this declaration was	   specializing.  */	return error_mark_node;      else	{	  tree gen_tmpl = most_general_template (tmpl);	  if (explicit_instantiation)	    {	      /* We don't set DECL_EXPLICIT_INSTANTIATION here; that		 is done by do_decl_instantiation later.  */ 	      int arg_depth = TMPL_ARGS_DEPTH (targs);	      int parm_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl));	      if (arg_depth > parm_depth)		{		  /* If TMPL is not the most general template (for		     example, if TMPL is a friend template that is		     injected into namespace scope), then there will		     be too many levels fo TARGS.  Remove some of them		     here.  */		  int i;		  tree new_targs;		  new_targs = make_temp_vec (parm_depth);		  for (i = arg_depth - parm_depth; i < arg_depth; ++i)		    TREE_VEC_ELT (new_targs, i - (arg_depth - parm_depth))		      = TREE_VEC_ELT (targs, i);		  targs = new_targs;		}		  	      decl = instantiate_template (tmpl, targs);	      return decl;	    }	  	  /* If we though that the DECL was a member function, but it	     turns out to be specializing a static member function,	     make DECL a static member function as well.  */	  if (DECL_STATIC_FUNCTION_P (tmpl)	      && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))	    {	      revert_static_member_fn (&decl, 0, 0);	      last_function_parms = TREE_CHAIN (last_function_parms);	    }	  /* Set up the DECL_TEMPLATE_INFO for DECL.  */	  DECL_TEMPLATE_INFO (decl) 	    = perm_tree_cons (tmpl, targs, NULL_TREE);	  /* Mangle the function name appropriately.  Note that we do	     not mangle specializations of non-template member	     functions of template classes, e.g. with	       template <class T> struct S { void f(); }	     and given the specialization 	       template <> void S<int>::f() {}	     we do not mangle S<int>::f() here.  That's because it's	     just an ordinary member function and doesn't need special	     treatment.  We do this here so that the ordinary,	     non-template, name-mangling algorith will not be used	     later.  */	  if ((is_member_template (tmpl) || ctype == NULL_TREE)	      && name_mangling_version >= 1)	    set_mangled_name_for_template_decl (decl);	  if (is_friend && !have_def)	    /* This is not really a declaration of a specialization.	       It's just the name of an instantiation.  But, it's not	       a request for an instantiation, either.  */	    SET_DECL_IMPLICIT_INSTANTIATION (decl);	  /* Register this specialization so that we can find it	     again.  */	  decl = register_specialization (decl, gen_tmpl, targs);	}    }    return decl;}/* TYPE is being declared.  Verify that the use of template headers   and such is reasonable.  Issue error messages if not.  */voidmaybe_check_template_type (type)     tree type;{  if (template_header_count)    {      /* We are in the scope of some `template <...>' header.  */      int context_depth 	= template_class_depth_real (TYPE_CONTEXT (type),				     /*count_specializations=*/1);      if (template_header_count <= context_depth)	/* This is OK; the template headers are for the context.  We	   are actually too lenient here; like	   check_explicit_specialization we should consider the number	   of template types included in the actual declaration.  For	   example, 	     template <class T> struct S {	       template <class U> template <class V>	       struct I {};	     }; 	   is illegal, but:	     template <class T> struct S {	       template <class U> struct I;	     }; 	     template <class T> template <class U.	     struct S<T>::I {};	   is not.  */	;       else if (template_header_count > context_depth + 1)	/* There are two many template parameter lists.  */	cp_error ("too many template parameter lists in declaration of `%T'", type);     }}/* Returns 1 iff PARMS1 and PARMS2 are identical sets of template   parameters.  These are represented in the same format used for   DECL_TEMPLATE_PARMS.  */int comp_template_parms (parms1, parms2)     tree parms1;     tree parms2;{  tree p1;  tree p2;  if (parms1 == parms2)    return 1;  for (p1 = parms1, p2 = parms2;        p1 != NULL_TREE && p2 != NULL_TREE;       p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2))    {      tree t1 = TREE_VALUE (p1);      tree t2 = TREE_VALUE (p2);      int i;      my_friendly_assert (TREE_CODE (t1) == TREE_VEC, 0);      my_friendly_assert (TREE_CODE (t2) == TREE_VEC, 0);      if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))	return 0;      for (i = 0; i < TREE_VEC_LENGTH (t2); ++i) 	{	  tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));	  tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));	  if (TREE_CODE (parm1) != TREE_CODE (parm2))	    return 0;	  if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM)	    continue;	  else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2)))	    return 0;	}    }  if ((p1 != NULL_TREE) != (p2 != NULL_TREE))    /* One set of parameters has more parameters lists than the       other.  */    return 0;  return 1;}/* Complain if DECL shadows a template parameter.   [temp.local]: A template-parameter shall not be redeclared within its   scope (including nested scopes).  */voidcheck_template_shadow (decl)     tree decl;{  tree olddecl;  /* If we're not in a template, we can't possibly shadow a template     parameter.  */  if (!current_template_parms)    return;  /* Figure out what we're shadowing.  */  if (TREE_CODE (decl) == OVERLOAD)    decl = OVL_CURRENT (decl);  olddecl = IDENTIFIER_VALUE (DECL_NAME (decl));  /* If there's no previous binding for this name, we're not shadowing     anything, let alone a template parameter.  */  if (!olddecl)    return;  /* If we're not shadowing a template parameter, we're done.  Note     that OLDDECL might be an OVERLOAD (or perhaps even an     ERROR_MARK), so we can't just blithely assume it to be a _DECL     node.  */  if (TREE_CODE_CLASS (TREE_CODE (olddecl)) != 'd'      || !DECL_TEMPLATE_PARM_P (olddecl))    return;  /* We check for decl != olddecl to avoid bogus errors for using a     name inside a class.  We check TPFI to avoid duplicate errors for     inline member templates.  */  if (decl == olddecl       || TEMPLATE_PARMS_FOR_INLINE (current_template_parms))    return;  cp_error_at ("declaration of `%#D'", decl);  cp_error_at (" shadows template parm `%#D'", olddecl);}/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,   ORIG_LEVEL, DECL, and TYPE.  */static treebuild_template_parm_index (index, level, orig_level, decl, type)     int index;     int level;     int orig_level;     tree decl;     tree type;{  tree t = make_node (TEMPLATE_PARM_INDEX);  TEMPLATE_PARM_IDX (t) = index;  TEMPLATE_PARM_LEVEL (t) = level;  TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;  TEMPLATE_PARM_DECL (t) = decl;  TREE_TYPE (t) = type;  return t;}/* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose   TEMPLATE_PARM_LEVEL has been decreased by LEVELS.  If such a   TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a   new one is created.  */static tree reduce_template_parm_level (index, type, levels)     tree index;     tree type;     int levels;{  if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE      || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))	  != TEMPLATE_PARM_LEVEL (index) - levels))    {      tree decl 	= build_decl (TREE_CODE (TEMPLATE_PARM_DECL (index)),		      DECL_NAME (TEMPLATE_PARM_DECL (index)),

⌨️ 快捷键说明

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