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

📄 class.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
		  if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))		    /* We can insert the new function right at the		       SLOTth position.  */		    break;		}  	      if (!TREE_VEC_ELT (method_vec, slot))		/* There is nothing in the Ith slot, so we can avoid		   moving anything.  */		; 	      else		{		  /* We know the last slot in the vector is empty		     because we know that at this point there's room		     for a new function.  */		  bcopy ((PTR) &TREE_VEC_ELT (method_vec, slot),			 (PTR) &TREE_VEC_ELT (method_vec, slot + 1),			 (len - slot - 1) * sizeof (tree));		  TREE_VEC_ELT (method_vec, slot) = NULL_TREE;		}	    }	}            if (template_class_depth (type))	/* TYPE is a template class.  Don't issue any errors now; wait	   until instantiation time to complain.  */	  ;      else	{	  tree fns;	  /* Check to see if we've already got this method.  */	  for (fns = TREE_VEC_ELT (method_vec, slot);	       fns;	       fns = OVL_NEXT (fns))	    {	      tree fn = OVL_CURRENT (fns);		 	      if (TREE_CODE (fn) != TREE_CODE (method))		continue;	      if (TREE_CODE (method) != TEMPLATE_DECL)		{		  /* [over.load] Member function declarations with the		     same name and the same parameter types cannot be		     overloaded if any of them is a static member		     function declaration.  */		  if (DECL_STATIC_FUNCTION_P (fn)		      != DECL_STATIC_FUNCTION_P (method))		    {		      tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));		      tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));		      if (! DECL_STATIC_FUNCTION_P (fn))			parms1 = TREE_CHAIN (parms1);		      else			parms2 = TREE_CHAIN (parms2);		      if (compparms (parms1, parms2))			cp_error ("`%#D' and `%#D' cannot be overloaded",				  fn, method);		    }		  /* Since this is an ordinary function in a		     non-template class, it's mangled name can be used		     as a unique identifier.  This technique is only		     an optimization; we would get the same results if		     we just used decls_match here.  */		  if (DECL_ASSEMBLER_NAME (fn) 		      != DECL_ASSEMBLER_NAME (method))		    continue;		}	      else if (!decls_match (fn, method))		continue;	      /* There has already been a declaration of this method		 or member template.  */	      cp_error_at ("`%D' has already been declared in `%T'", 			   method, type);	      /* We don't call duplicate_decls here to merge the		 declarations because that will confuse things if the		 methods have inline definitions.  In particular, we		 will crash while processing the definitions.  */	      return;	    }	}      /* Actually insert the new method.  */      TREE_VEC_ELT (method_vec, slot) 	= build_overload (method, TREE_VEC_ELT (method_vec, slot));      /* Add the new binding.  */       if (!DECL_CONSTRUCTOR_P (method)	  && !DECL_DESTRUCTOR_P (method))	push_class_level_binding (DECL_NAME (method),				  TREE_VEC_ELT (method_vec, slot));    }  pop_obstacks ();}/* Subroutines of finish_struct.  *//* Look through the list of fields for this struct, deleting   duplicates as we go.  This must be recursive to handle   anonymous unions.   FIELD is the field which may not appear anywhere in FIELDS.   FIELD_PTR, if non-null, is the starting point at which   chained deletions may take place.   The value returned is the first acceptable entry found   in FIELDS.   Note that anonymous fields which are not of UNION_TYPE are   not duplicates, they are just anonymous fields.  This happens   when we have unnamed bitfields, for example.  */static treedelete_duplicate_fields_1 (field, fields)     tree field, fields;{  tree x;  tree prev = 0;  if (DECL_NAME (field) == 0)    {      if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE)	return fields;      for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x))	fields = delete_duplicate_fields_1 (x, fields);      return fields;    }  else    {      for (x = fields; x; prev = x, x = TREE_CHAIN (x))	{	  if (DECL_NAME (x) == 0)	    {	      if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE)		continue;	      TYPE_FIELDS (TREE_TYPE (x))		= delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x)));	      if (TYPE_FIELDS (TREE_TYPE (x)) == 0)		{		  if (prev == 0)		    fields = TREE_CHAIN (fields);		  else		    TREE_CHAIN (prev) = TREE_CHAIN (x);		}	    }	  else	    {	      if (DECL_NAME (field) == DECL_NAME (x))		{		  if (TREE_CODE (field) == CONST_DECL		      && TREE_CODE (x) == CONST_DECL)		    cp_error_at ("duplicate enum value `%D'", x);		  else if (TREE_CODE (field) == CONST_DECL			   || TREE_CODE (x) == CONST_DECL)		    cp_error_at ("duplicate field `%D' (as enum and non-enum)",				x);		  else if (DECL_DECLARES_TYPE_P (field)			   && DECL_DECLARES_TYPE_P (x))		    {		      if (same_type_p (TREE_TYPE (field), TREE_TYPE (x)))			continue;		      cp_error_at ("duplicate nested type `%D'", x);		    }		  else if (DECL_DECLARES_TYPE_P (field)			   || DECL_DECLARES_TYPE_P (x))		    {		      /* Hide tag decls.  */		      if ((TREE_CODE (field) == TYPE_DECL			   && DECL_ARTIFICIAL (field))			  || (TREE_CODE (x) == TYPE_DECL			      && DECL_ARTIFICIAL (x)))			continue;		      cp_error_at ("duplicate field `%D' (as type and non-type)",				   x);		    }		  else		    cp_error_at ("duplicate member `%D'", x);		  if (prev == 0)		    fields = TREE_CHAIN (fields);		  else		    TREE_CHAIN (prev) = TREE_CHAIN (x);		}	    }	}    }  return fields;}static voiddelete_duplicate_fields (fields)     tree fields;{  tree x;  for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x))    TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));}/* Change the access of FDECL to ACCESS in T.  The access to FDECL is   along the path given by BINFO.  Return 1 if change was legit,   otherwise return 0.  */static intalter_access (t, binfo, fdecl, access)     tree t;     tree binfo;     tree fdecl;     tree access;{  tree elem = purpose_member (t, DECL_ACCESS (fdecl));  if (elem)    {      if (TREE_VALUE (elem) != access)	{	  if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)	    cp_error_at ("conflicting access specifications for method `%D', ignored", TREE_TYPE (fdecl));	  else	    error ("conflicting access specifications for field `%s', ignored",		   IDENTIFIER_POINTER (DECL_NAME (fdecl)));	}      else	{	  /* They're changing the access to the same thing they changed	     it to before.  That's OK.  */	  ;	}    }  else    {      enforce_access (binfo, fdecl);      DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));      return 1;    }  return 0;}/* Process the USING_DECL, which is a member of T.  The METHOD_VEC, if   non-NULL, is the methods of T.  The FIELDS are the fields of T.  */static voidhandle_using_decl (using_decl, t, method_vec, fields)     tree using_decl;     tree t;     tree method_vec;     tree fields;{  tree ctype = DECL_INITIAL (using_decl);  tree name = DECL_NAME (using_decl);  tree access    = TREE_PRIVATE (using_decl) ? access_private_node    : TREE_PROTECTED (using_decl) ? access_protected_node    : access_public_node;  tree fdecl, binfo;  tree flist = NULL_TREE;  tree tmp;  int i;  int n_methods;  binfo = binfo_or_else (ctype, t);  if (! binfo)    return;    if (name == constructor_name (ctype)      || name == constructor_name_full (ctype))    {      cp_error_at ("using-declaration for constructor", using_decl);      return;    }  fdecl = lookup_member (binfo, name, 0, 0);    if (!fdecl)    {      cp_error_at ("no members matching `%D' in `%#T'", using_decl, ctype);      return;    }  /* Functions are represented as TREE_LIST, with the purpose     being the type and the value the functions. Other members     come as themselves. */  if (TREE_CODE (fdecl) == TREE_LIST)    /* Ignore base type this came from. */    fdecl = TREE_VALUE (fdecl);  if (TREE_CODE (fdecl) == OVERLOAD)    {      /* We later iterate over all functions. */      flist = fdecl;      fdecl = OVL_FUNCTION (flist);    }    name = DECL_NAME (fdecl);  n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;  for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); i++)    if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))	== name)      {	cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);	cp_error_at ("  because of local method `%#D' with same name",		     OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));	return;      }  if (! DECL_LANG_SPECIFIC (fdecl))    /* We don't currently handle DECL_ACCESS for TYPE_DECLs; just return.  */    return;    for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp))    if (DECL_NAME (tmp) == name)      {	cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);	cp_error_at ("  because of local field `%#D' with same name", tmp);	return;      }    /* Make type T see field decl FDECL with access ACCESS.*/  if (flist)    {      while (flist)	{	  if (alter_access (t, binfo, OVL_FUNCTION (flist), 			    access) == 0)	    return;	  flist = OVL_CHAIN (flist);	}    }  else    alter_access (t, binfo, fdecl, access);}struct base_info{  int has_virtual;  int max_has_virtual;  tree vfield;  tree vfields;  tree rtti;  char cant_have_default_ctor;  char cant_have_const_ctor;  char no_const_asn_ref;};/* Record information about type T derived from its base classes.   Store most of that information in T itself, and place the   remaining information in the struct BASE_INFO.   Propagate basetype offsets throughout the lattice.  Note that the   lattice topped by T is really a pair: it's a DAG that gives the   structure of the derivation hierarchy, and it's a list of the   virtual baseclasses that appear anywhere in the DAG.  When a vbase   type appears in the DAG, it's offset is 0, and it's children start   their offsets from that point.  When a vbase type appears in the list,   its offset is the offset it has in the hierarchy, and its children's   offsets include that offset in theirs.   Returns the index of the first base class to have virtual functions,   or -1 if no such base class.  */static intfinish_base_struct (t, b)     tree t;     struct base_info *b;{  tree binfos = TYPE_BINFO_BASETYPES (t);  int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;  int first_vfn_base_index = -1;  bzero ((char *) b, sizeof (struct base_info));  for (i = 0; i < n_baseclasses; i++)    {      tree base_binfo = TREE_VEC_ELT (binfos, i);      tree basetype = BINFO_TYPE (base_binfo);      /* Effective C++ rule 14.  We only need to check TYPE_VIRTUAL_P	 here because the case of virtual functions but non-virtual	 dtor is handled in finish_struct_1.  */      if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)	  && TYPE_HAS_DESTRUCTOR (basetype))	cp_warning ("base class `%#T' has a non-virtual destructor", basetype);      /* If the type of basetype is incomplete, then	 we already complained about that fact	 (and we should have fixed it up as well).  */      if (TYPE_SIZE (basetype) == 0)	{	  int j;	  /* The base type is of incomplete type.  It is	     probably best to pretend that it does not	     exist.  */	  if (i == n_baseclasses-1)	    TREE_VEC_ELT (binfos, i) = NULL_TREE;	  TREE_VEC_LENGTH (binfos) -= 1;	  n_baseclasses -= 1;	  for (j = i; j+1 < n_baseclasses; j++)	    TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1);	}      if (! TYPE_HAS_CONST_INIT_REF (basetype))	b->cant_have_const_ctor = 1;      if (TYPE_HAS_CONSTRUCTOR (basetype)	  && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))	{	  b->cant_have_default_ctor = 1;	  if (! TYPE_HAS_CONSTRUCTOR (t))	    {	      cp_pedwarn ("base `%T' with only non-default constructor",			  basetype);	      cp_pedwarn ("in class without a constructor");	    }	}      if (TYPE_HAS_ASSIGN_REF (basetype)	  && !TYPE_HAS_CONST_ASSIGN_REF (basetype))	b->no_const_asn_ref = 1;

⌨️ 快捷键说明

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