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

📄 pt.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Handle parameterized types (templates) for GNU C++.   Copyright (C) 1992, 93-97, 1998, 1999 Free Software Foundation, Inc.   Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.   Rewritten by Jason Merrill (jason@cygnus.com).This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* Known bugs or deficiencies include:     all methods must be provided in header files; can't use a source     file that contains only the method templates and "just win".  */#include "config.h"#include "system.h"#include "obstack.h"#include "tree.h"#include "flags.h"#include "cp-tree.h"#include "decl.h"#include "parse.h"#include "lex.h"#include "output.h"#include "defaults.h"#include "except.h"#include "toplev.h"#include "rtl.h"#include "varray.h"/* The type of functions taking a tree, and some additional data, and   returning an int.  */typedef int (*tree_fn_t) PROTO((tree, void*));extern struct obstack permanent_obstack;extern int lineno;extern char *input_filename;tree current_template_parms;HOST_WIDE_INT processing_template_decl;/* The PENDING_TEMPLATES is a TREE_LIST of templates whose   instantiations have been deferred, either because their definitions   were not yet available, or because we were putting off doing the   work.  The TREE_PURPOSE of each entry is a SRCLOC indicating where   the instantiate request occurred; the TREE_VALUE is a either a DECL   (for a function or static data member), or a TYPE (for a class)   indicating what we are hoping to instantiate.  */static tree pending_templates;static tree *template_tail = &pending_templates;static tree maybe_templates;static tree *maybe_template_tail = &maybe_templates;int minimal_parse_mode;int processing_specialization;int processing_explicit_instantiation;int processing_template_parmlist;static int template_header_count;static tree saved_trees;static varray_type inline_parm_levels;static size_t inline_parm_levels_used;#define obstack_chunk_alloc xmalloc#define obstack_chunk_free free#define UNIFY_ALLOW_NONE 0#define UNIFY_ALLOW_MORE_CV_QUAL 1#define UNIFY_ALLOW_LESS_CV_QUAL 2#define UNIFY_ALLOW_DERIVED 4#define UNIFY_ALLOW_INTEGER 8#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is			     virtual, or a base class of a virtual			     base.  */#define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current			     type with the desired type.  */static int resolve_overloaded_unification PROTO((tree, tree, tree, tree,						 unification_kind_t, int));static int try_one_overload PROTO((tree, tree, tree, tree, tree,				   unification_kind_t, int));static int unify PROTO((tree, tree, tree, tree, int));static void add_pending_template PROTO((tree));static int push_tinst_level PROTO((tree));static tree classtype_mangled_name PROTO((tree));static char *mangle_class_name_for_template PROTO((char *, tree, tree));static tree tsubst_expr_values PROTO((tree, tree));static int list_eq PROTO((tree, tree));static tree get_class_bindings PROTO((tree, tree, tree));static tree coerce_template_parms PROTO((tree, tree, tree, int, int));static void tsubst_enum	PROTO((tree, tree, tree));static tree add_to_template_args PROTO((tree, tree));static tree add_outermost_template_args PROTO((tree, tree));static void maybe_adjust_types_for_deduction PROTO((unification_kind_t, tree*,						    tree*)); static int  type_unification_real PROTO((tree, tree, tree, tree,					 int, unification_kind_t, int));static void note_template_header PROTO((int));static tree maybe_fold_nontype_arg PROTO((tree));static tree convert_nontype_argument PROTO((tree, tree));static tree convert_template_argument PROTO ((tree, tree, tree, int,					      int , tree));static tree get_bindings_overload PROTO((tree, tree, tree));static int for_each_template_parm PROTO((tree, tree_fn_t, void*));static tree build_template_parm_index PROTO((int, int, int, tree, tree));static int inline_needs_template_parms PROTO((tree));static void push_inline_template_parms_recursive PROTO((tree, int));static tree retrieve_specialization PROTO((tree, tree));static tree register_specialization PROTO((tree, tree, tree));static int unregister_specialization PROTO((tree, tree));static tree reduce_template_parm_level PROTO((tree, tree, int));static tree build_template_decl PROTO((tree, tree));static int mark_template_parm PROTO((tree, void *));static tree tsubst_friend_function PROTO((tree, tree));static tree tsubst_friend_class PROTO((tree, tree));static tree get_bindings_real PROTO((tree, tree, tree, int));static int template_decl_level PROTO((tree));static tree maybe_get_template_decl_from_type_decl PROTO((tree));static int check_cv_quals_for_unify PROTO((int, tree, tree));static tree tsubst_template_arg_vector PROTO((tree, tree, int));static tree tsubst_template_parms PROTO((tree, tree, int));static void regenerate_decl_from_template PROTO((tree, tree));static tree most_specialized PROTO((tree, tree, tree));static tree most_specialized_class PROTO((tree, tree));static tree most_general_template PROTO((tree));static void set_mangled_name_for_template_decl PROTO((tree));static int template_class_depth_real PROTO((tree, int));static tree tsubst_aggr_type PROTO((tree, tree, int, tree, int));static tree tsubst_decl PROTO((tree, tree, tree, tree));static tree tsubst_arg_types PROTO((tree, tree, int, tree));static tree tsubst_function_type PROTO((tree, tree, int, tree));static void check_specialization_scope PROTO((void));static tree process_partial_specialization PROTO((tree));static void set_current_access_from_decl PROTO((tree));static void check_default_tmpl_args PROTO((tree, tree, int, int));static tree tsubst_call_declarator_parms PROTO((tree, tree, int, tree));static tree get_template_base_recursive PROTO((tree, tree,					       tree, tree, tree, int)); static tree get_template_base PROTO((tree, tree, tree, tree));static tree try_class_unification PROTO((tree, tree, tree, tree));static int coerce_template_template_parms PROTO((tree, tree, int,						 tree, tree));static tree determine_specialization PROTO((tree, tree, tree *, int));static int template_args_equal PROTO((tree, tree));static void print_template_context PROTO((int));static int has_pvbases_p PROTO((tree, tree));/* We use TREE_VECs to hold template arguments.  If there is only one   level of template arguments, then the TREE_VEC contains the   arguments directly.  If there is more than one level of template   arguments, then each entry in the TREE_VEC is itself a TREE_VEC,   containing the template arguments for a single level.  The first   entry in the outer TREE_VEC is the outermost level of template   parameters; the last is the innermost.     It is incorrect to ever form a template argument vector containing   only one level of arguments, but which is a TREE_VEC containing as   its only entry the TREE_VEC for that level.  *//* Non-zero if the template arguments is actually a vector of vectors,   rather than just a vector.  */#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \  (NODE != NULL_TREE						\   && TREE_CODE (NODE) == TREE_VEC				\   && TREE_VEC_LENGTH (NODE) > 0				\   && TREE_VEC_ELT (NODE, 0) != NULL_TREE			\   && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)/* The depth of a template argument vector.  When called directly by   the parser, we use a TREE_LIST rather than a TREE_VEC to represent   template arguments.  In fact, we may even see NULL_TREE if there   are no template arguments.  In both of those cases, there is only   one level of template arguments.  */#define TMPL_ARGS_DEPTH(NODE)					\  (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1)/* The LEVELth level of the template ARGS.  Note that template   parameter levels are indexed from 1, not from 0.  */#define TMPL_ARGS_LEVEL(ARGS, LEVEL)		\  (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) 	\   ? TREE_VEC_ELT ((ARGS), (LEVEL) - 1) : ARGS)/* Set the LEVELth level of the template ARGS to VAL.  This macro does   not work with single-level argument vectors.  */#define SET_TMPL_ARGS_LEVEL(ARGS, LEVEL, VAL)	\  (TREE_VEC_ELT ((ARGS), (LEVEL) - 1) = (VAL))/* Accesses the IDXth parameter in the LEVELth level of the ARGS.  */#define TMPL_ARG(ARGS, LEVEL, IDX)				\  (TREE_VEC_ELT (TMPL_ARGS_LEVEL (ARGS, LEVEL), IDX))/* Set the IDXth element in the LEVELth level of ARGS to VAL.  This   macro does not work with single-level argument vectors.  */#define SET_TMPL_ARG(ARGS, LEVEL, IDX, VAL)			\  (TREE_VEC_ELT (TREE_VEC_ELT ((ARGS), (LEVEL) - 1), (IDX)) = (VAL))/* Given a single level of template arguments in NODE, return the   number of arguments.  */#define NUM_TMPL_ARGS(NODE) 				\  ((NODE) == NULL_TREE ? 0 				\   : (TREE_CODE (NODE) == TREE_VEC 			\      ? TREE_VEC_LENGTH (NODE) : list_length (NODE)))/* The number of levels of template parameters given by NODE.  */#define TMPL_PARMS_DEPTH(NODE) \  (TREE_INT_CST_HIGH (TREE_PURPOSE (NODE)))/* Do any processing required when DECL (a member template declaration   using TEMPLATE_PARAMETERS as its innermost parameter list) is   finished.  Returns the TEMPLATE_DECL corresponding to DECL, unless   it is a specialization, in which case the DECL itself is returned.  */treefinish_member_template_decl (decl)  tree decl;{  if (decl == NULL_TREE || decl == void_type_node)    return NULL_TREE;  else if (decl == error_mark_node)    /* By returning NULL_TREE, the parser will just ignore this       declaration.  We have already issued the error.  */    return NULL_TREE;  else if (TREE_CODE (decl) == TREE_LIST)    {      /* Assume that the class is the only declspec.  */      decl = TREE_VALUE (decl);      if (IS_AGGR_TYPE (decl) && CLASSTYPE_TEMPLATE_INFO (decl)	  && ! CLASSTYPE_TEMPLATE_SPECIALIZATION (decl))	{	  tree tmpl = CLASSTYPE_TI_TEMPLATE (decl);	  check_member_template (tmpl);	  return tmpl;	}      return NULL_TREE;    }  else if (DECL_TEMPLATE_INFO (decl))    {      if (!DECL_TEMPLATE_SPECIALIZATION (decl))	{	  check_member_template (DECL_TI_TEMPLATE (decl));	  return DECL_TI_TEMPLATE (decl);	}      else	return decl;    }   else    cp_error ("invalid member template declaration `%D'", decl);  return error_mark_node;}/* Returns the template nesting level of the indicated class TYPE.      For example, in:     template <class T>     struct A     {       template <class U>       struct B {};     };   A<T>::B<U> has depth two, while A<T> has depth one.     Both A<T>::B<int> and A<int>::B<U> have depth one, if   COUNT_SPECIALIZATIONS is 0 or if they are instantiations, not   specializations.     This function is guaranteed to return 0 if passed NULL_TREE so   that, for example, `template_class_depth (current_class_type)' is   always safe.  */static int template_class_depth_real (type, count_specializations)     tree type;     int count_specializations;{  int depth;  for (depth = 0;        type && TREE_CODE (type) != NAMESPACE_DECL;       type = (TREE_CODE (type) == FUNCTION_DECL) 	 ? DECL_REAL_CONTEXT (type) : TYPE_CONTEXT (type))    {      if (TREE_CODE (type) != FUNCTION_DECL)	{	  if (CLASSTYPE_TEMPLATE_INFO (type)	      && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))	      && ((count_specializations		   && CLASSTYPE_TEMPLATE_SPECIALIZATION (type))		  || uses_template_parms (CLASSTYPE_TI_ARGS (type))))	    ++depth;	}      else 	{	  if (DECL_TEMPLATE_INFO (type)	      && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type))	      && ((count_specializations		   && DECL_TEMPLATE_SPECIALIZATION (type))		  || uses_template_parms (DECL_TI_ARGS (type))))	    ++depth;	}    }  return depth;}/* Returns the template nesting level of the indicated class TYPE.   Like template_class_depth_real, but instantiations do not count in   the depth.  */int template_class_depth (type)     tree type;{  return template_class_depth_real (type, /*count_specializations=*/0);}/* Returns 1 if processing DECL as part of do_pending_inlines   needs us to push template parms.  */static intinline_needs_template_parms (decl)     tree decl;{  if (! DECL_TEMPLATE_INFO (decl))    return 0;  return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl)))	  > (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl)));}/* Subroutine of maybe_begin_member_template_processing.   Push the template parms in PARMS, starting from LEVELS steps into the   chain, and ending at the beginning, since template parms are listed   innermost first.  */static voidpush_inline_template_parms_recursive (parmlist, levels)     tree parmlist;     int levels;{  tree parms = TREE_VALUE (parmlist);  int i;  if (levels > 1)    push_inline_template_parms_recursive (TREE_CHAIN (parmlist), levels - 1);  ++processing_template_decl;  current_template_parms    = tree_cons (build_int_2 (0, processing_template_decl),		 parms, current_template_parms);  TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1;  pushlevel (0);  for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)     {      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));      my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (parm)) == 'd', 0);      switch (TREE_CODE (parm))	{	case TYPE_DECL:	case TEMPLATE_DECL:	  pushdecl (parm);	  break;	case PARM_DECL:	  {	    /* Make a CONST_DECL as is done in process_template_parm.	       It is ugly that we recreate this here; the original	       version built in process_template_parm is no longer	       available.  */	    tree decl = build_decl (CONST_DECL, DECL_NAME (parm),				    TREE_TYPE (parm));	    SET_DECL_ARTIFICIAL (decl);	    DECL_INITIAL (decl) = DECL_INITIAL (parm);	    DECL_TEMPLATE_PARM_P (decl) = 1;	    pushdecl (decl);	  }	  break;	default:	  my_friendly_abort (0);	}    }}/* Restore the template parameter context for a member template or   a friend template defined in a class definition.  */voidmaybe_begin_member_template_processing (decl)     tree decl;{  tree parms;  int levels = 0;  if (inline_needs_template_parms (decl))    {      parms = DECL_TEMPLATE_PARMS (most_general_template (decl));      levels = TMPL_PARMS_DEPTH (parms) - processing_template_decl;      if (DECL_TEMPLATE_SPECIALIZATION (decl))	{	  --levels;	  parms = TREE_CHAIN (parms);	}      push_inline_template_parms_recursive (parms, levels);    }  /* Remember how many levels of template parameters we pushed so that

⌨️ 快捷键说明

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