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

📄 pt.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
		    goto maybe_error;		  }	      }	    if (r == NULL_TREE)	      {	      no_match:		cp_error		  (found		   ? "template for method `%D' doesn't match any in class `%T'"		   : "method `%D' not found in class `%T'", name, ctx);		if (in_decl)		  cp_error_at ("in attempt to instantiate `%D' declared at this point in file", in_decl);		return error_mark_node;	      }	  }	else	  {	    r = DECL_NAME (t);	    {	      tree decls;	      int got_it = 0;	      decls = lookup_name_nonclass (r);	      if (decls == NULL_TREE)		/* no match */;	      else if (TREE_CODE (decls) == TREE_LIST)		for (decls = TREE_VALUE (decls); decls ;		     decls = DECL_CHAIN (decls))		  {		    if (TREE_CODE (decls) == FUNCTION_DECL			&& TREE_TYPE (decls) == type)		      {			got_it = 1;			r = decls;			break;		      }		  }	      else		{		  tree val = decls;		  decls = NULL_TREE;		  if (TREE_CODE (val) == FUNCTION_DECL		      && TREE_TYPE (val) == type)		    {		      got_it = 1;		      r = val;		    }		}	      if (!got_it)		{		  tree a = build_decl_overload (r, TYPE_VALUES (type),						DECL_CONTEXT (t) != NULL_TREE);		  r = build_lang_decl (FUNCTION_DECL, r, type);		  DECL_ASSEMBLER_NAME (r) = a;		}	      else if (TREE_STATIC (r))		{		  /* This overrides the template version, use it. */		  return r;		}	    }	  }	TREE_PUBLIC (r) = 1;	DECL_EXTERNAL (r) = 1;	TREE_STATIC (r) = 0;	DECL_INTERFACE_KNOWN (r) = 0;	DECL_INLINE (r) = DECL_INLINE (t);	DECL_THIS_INLINE (r) = DECL_THIS_INLINE (t);	TREE_READONLY (r) = TREE_READONLY (t);	TREE_THIS_VOLATILE (r) = TREE_THIS_VOLATILE (t);	{#if 0				/* Maybe later.  -jason  */	  struct tinst_level *til = tinst_for_decl();	  /* should always be true under new approach */	  if (til)	    {	      DECL_SOURCE_FILE (r) = til->file;	      DECL_SOURCE_LINE (r) = til->line;	    }	  else#endif	    {	      DECL_SOURCE_FILE (r) = DECL_SOURCE_FILE (t);	      DECL_SOURCE_LINE (r) = DECL_SOURCE_LINE (t);	    }	}	DECL_CLASS_CONTEXT (r) = tsubst (DECL_CLASS_CONTEXT (t), args, nargs, t);	make_decl_rtl (r, NULL_PTR, 1);	DECL_ARGUMENTS (r) = fnargs;	DECL_RESULT (r) = result;#if 0	if (DECL_CONTEXT (t) == NULL_TREE	    || TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) != 't')	  push_overloaded_decl_top_level (r, 0);#endif	return r;      }    case PARM_DECL:      {	tree r;	r = build_decl (PARM_DECL, DECL_NAME (t), type);	DECL_INITIAL (r) = TREE_TYPE (r);	DECL_ARTIFICIAL (r) = DECL_ARTIFICIAL (t);#ifdef PROMOTE_PROTOTYPES	if ((TREE_CODE (type) == INTEGER_TYPE	     || TREE_CODE (type) == ENUMERAL_TYPE)	    && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))	  DECL_ARG_TYPE (r) = integer_type_node;#endif	if (TREE_CHAIN (t))	  TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, nargs, TREE_CHAIN (t));	return r;      }    case TREE_LIST:      {	tree purpose, value, chain, result;	int via_public, via_virtual, via_protected;	if (t == void_list_node)	  return t;	via_public = TREE_VIA_PUBLIC (t);	via_protected = TREE_VIA_PROTECTED (t);	via_virtual = TREE_VIA_VIRTUAL (t);	purpose = TREE_PURPOSE (t);	if (purpose)	  purpose = tsubst (purpose, args, nargs, in_decl);	value = TREE_VALUE (t);	if (value)	  value = tsubst (value, args, nargs, in_decl);	chain = TREE_CHAIN (t);	if (chain && chain != void_type_node)	  chain = tsubst (chain, args, nargs, in_decl);	if (purpose == TREE_PURPOSE (t)	    && value == TREE_VALUE (t)	    && chain == TREE_CHAIN (t))	  return t;	result = hash_tree_cons (via_public, via_virtual, via_protected,				 purpose, value, chain);	TREE_PARMLIST (result) = TREE_PARMLIST (t);	return result;      }    case TREE_VEC:      {	int len = TREE_VEC_LENGTH (t), need_new = 0, i;	tree *elts = (tree *) alloca (len * sizeof (tree));	bzero ((char *) elts, len * sizeof (tree));	for (i = 0; i < len; i++)	  {	    elts[i] = tsubst (TREE_VEC_ELT (t, i), args, nargs, in_decl);	    if (elts[i] != TREE_VEC_ELT (t, i))	      need_new = 1;	  }	if (!need_new)	  return t;	t = make_tree_vec (len);	for (i = 0; i < len; i++)	  TREE_VEC_ELT (t, i) = elts[i];	return t;      }    case POINTER_TYPE:    case REFERENCE_TYPE:      {	tree r;	enum tree_code code;	if (type == TREE_TYPE (t))	  return t;	code = TREE_CODE (t);	if (code == POINTER_TYPE)	  r = build_pointer_type (type);	else	  r = build_reference_type (type);	r = cp_build_type_variant (r, TYPE_READONLY (t), TYPE_VOLATILE (t));	/* Will this ever be needed for TYPE_..._TO values?  */	layout_type (r);	return r;      }    case OFFSET_TYPE:      return build_offset_type	(tsubst (TYPE_OFFSET_BASETYPE (t), args, nargs, in_decl), type);    case FUNCTION_TYPE:    case METHOD_TYPE:      {	tree values = TYPE_ARG_TYPES (t);	tree context = TYPE_CONTEXT (t);	tree new_value;	/* Don't bother recursing if we know it won't change anything.	*/	if (values != void_list_node)	  values = tsubst (values, args, nargs, in_decl);	if (context)	  context = tsubst (context, args, nargs, in_decl);	/* Could also optimize cases where return value and	   values have common elements (e.g., T min(const &T, const T&).  */	/* If the above parameters haven't changed, just return the type.  */	if (type == TREE_TYPE (t)	    && values == TYPE_VALUES (t)	    && context == TYPE_CONTEXT (t))	  return t;	/* Construct a new type node and return it.  */	if (TREE_CODE (t) == FUNCTION_TYPE	    && context == NULL_TREE)	  {	    new_value = build_function_type (type, values);	  }	else if (context == NULL_TREE)	  {	    tree base = tsubst (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))),				args, nargs, in_decl);	    new_value = build_cplus_method_type (base, type,						 TREE_CHAIN (values));	  }	else	  {	    new_value = make_node (TREE_CODE (t));	    TREE_TYPE (new_value) = type;	    TYPE_CONTEXT (new_value) = context;	    TYPE_VALUES (new_value) = values;	    TYPE_SIZE (new_value) = TYPE_SIZE (t);	    TYPE_ALIGN (new_value) = TYPE_ALIGN (t);	    TYPE_MODE (new_value) = TYPE_MODE (t);	    if (TYPE_METHOD_BASETYPE (t))	      TYPE_METHOD_BASETYPE (new_value) = tsubst (TYPE_METHOD_BASETYPE (t),							 args, nargs, in_decl);	    /* Need to generate hash value.  */	    my_friendly_abort (84);	  }	new_value = build_type_variant (new_value,					TYPE_READONLY (t),					TYPE_VOLATILE (t));	return new_value;      }    case ARRAY_TYPE:      {	tree domain = tsubst (TYPE_DOMAIN (t), args, nargs, in_decl);	tree r;	if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))	  return t;	r = build_cplus_array_type (type, domain);	return r;      }    case UNINSTANTIATED_P_TYPE:      {	int nparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (UPT_TEMPLATE (t)));	tree argvec = make_tree_vec (nparms);	tree parmvec = UPT_PARMS (t);	int i;	tree id, rt;	for (i = 0; i < nparms; i++)	  TREE_VEC_ELT (argvec, i) = tsubst (TREE_VEC_ELT (parmvec, i),					     args, nargs, in_decl);	id = lookup_template_class (DECL_NAME (UPT_TEMPLATE (t)), argvec, NULL_TREE);	if (! IDENTIFIER_HAS_TYPE_VALUE (id)) {	  instantiate_class_template(id, 0);	  /* set up pending_classes */	  add_pending_template (id);	  TYPE_MAIN_VARIANT (IDENTIFIER_TYPE_VALUE (id)) =	    IDENTIFIER_TYPE_VALUE (id);	}        rt = IDENTIFIER_TYPE_VALUE (id);	/* kung: this part handles nested type in template definition */        	if ( !ANON_AGGRNAME_P (DECL_NAME(TYPE_NAME(t))))          {	    rt = search_nested_type_in_tmpl (rt, t);          }	return build_type_variant (rt, TYPE_READONLY (t), TYPE_VOLATILE (t));      }    case MINUS_EXPR:    case PLUS_EXPR:      return fold (build (TREE_CODE (t), TREE_TYPE (t),			  tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),			  tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl)));    case NEGATE_EXPR:    case NOP_EXPR:      return fold (build1 (TREE_CODE (t), TREE_TYPE (t),			   tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl)));    default:      sorry ("use of `%s' in function template",	     tree_code_name [(int) TREE_CODE (t)]);      return error_mark_node;    }}treeinstantiate_template (tmpl, targ_ptr)     tree tmpl, *targ_ptr;{  tree targs, fndecl;  int i, len;  struct pending_inline *p;  struct template_info *t;  struct obstack *old_fmp_obstack;  extern struct obstack *function_maybepermanent_obstack;  push_obstacks (&permanent_obstack, &permanent_obstack);  old_fmp_obstack = function_maybepermanent_obstack;  function_maybepermanent_obstack = &permanent_obstack;  my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283);  len = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (tmpl));  i = len;  while (i--)    targ_ptr[i] = copy_to_permanent (targ_ptr[i]);  for (fndecl = DECL_TEMPLATE_INSTANTIATIONS (tmpl);       fndecl; fndecl = TREE_CHAIN (fndecl))    {      tree *t1 = &TREE_VEC_ELT (TREE_PURPOSE (fndecl), 0);      for (i = len - 1; i >= 0; i--)	if (simple_cst_equal (t1[i], targ_ptr[i]) <= 0)	  goto no_match;      /* Here, we have a match.  */      fndecl = TREE_VALUE (fndecl);      goto exit;    no_match:      ;    }  targs = make_tree_vec (len);  i = len;  while (i--)    TREE_VEC_ELT (targs, i) = targ_ptr[i];  /* substitute template parameters */  fndecl = tsubst (DECL_RESULT (tmpl), targ_ptr,		   TREE_VEC_LENGTH (targs), tmpl);  if (fndecl == error_mark_node)    goto exit;  assemble_external (fndecl);  /* If it's a static member fn in the template, we need to change it     into a FUNCTION_TYPE and chop off its this pointer.  */  if (TREE_CODE (TREE_TYPE (DECL_RESULT (tmpl))) == METHOD_TYPE      && DECL_STATIC_FUNCTION_P (fndecl))    {      revert_static_member_fn (&DECL_RESULT (tmpl), NULL, NULL);      /* Chop off the this pointer that grokclassfn so kindly added	 for us (it didn't know yet if the fn was static or not).  */      DECL_ARGUMENTS (fndecl) = TREE_CHAIN (DECL_ARGUMENTS (fndecl));    }       t = DECL_TEMPLATE_INFO (tmpl);  /* If we have a preexisting version of this function, don't expand     the template version, use the other instead.  */  if (TREE_STATIC (fndecl) || DECL_TEMPLATE_SPECIALIZATION (fndecl))    {      SET_DECL_TEMPLATE_SPECIALIZATION (fndecl);      p = (struct pending_inline *)0;    }  else if (t->text)    {      SET_DECL_IMPLICIT_INSTANTIATION (fndecl);      repo_template_used (fndecl);      p = (struct pending_inline *) permalloc (sizeof (struct pending_inline));      p->parm_vec = t->parm_vec;      p->bindings = targs;      p->can_free = 0;      p->deja_vu = 0;      p->buf = t->text;      p->len = t->length;      p->fndecl = fndecl;      {	int l = lineno;	char * f = input_filename;	lineno = p->lineno = t->lineno;	input_filename = p->filename = t->filename;	extract_interface_info ();	if (interface_unknown && flag_external_templates)	  {	    if (DECL_CLASS_CONTEXT (fndecl)		&& CLASSTYPE_INTERFACE_KNOWN (DECL_CLASS_CONTEXT (fndecl)))	      {		interface_unknown = 0;		interface_only		  = CLASSTYPE_INTERFACE_ONLY (DECL_CLASS_CONTEXT (fndecl));	      }	    else if (! DECL_IN_SYSTEM_HEADER (tmpl))	      warn_if_unknown_interface (tmpl);	  }	if (interface_unknown || ! flag_external_templates)	  p->interface = 1;		/* unknown */	else	  p->interface = interface_only ? 0 : 2;	lineno = l;	input_filename = f;	extract_interface_info ();      }    }  else    p = (struct pending_inline *)0;  DECL_TEMPLATE_INSTANTIATIONS (tmpl) =    tree_cons (targs, fndecl, DECL_TEMPLATE_INSTANTIATIONS (tmpl));  if (p == (struct pending_inline *)0)    {      /* do nothing */    }  else if (DECL_INLINE (fndecl))    {      DECL_PENDING_INLINE_INFO (fndecl) = p;      p->next = pending_inlines;      pending_inlines = p;    }  else    {      p->next = pending_template_expansions;      pending_template_expansions = p;    } exit:  function_maybepermanent_obstack = old_fmp_obstack;  pop_obstacks ();  return fndecl;}/* classlevel should now never be true.  jason 4/12/94 */voidundo_template_name_overload (id, classlevel)     tree id;     int classlevel;{  tree template;  template = IDENTIFIER_TEMPLATE (id);  if (!template)    return;

⌨️ 快捷键说明

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