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

📄 init.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* Increment vlist by number of base's vbase classes. */      expr = build_int_2 (pvbasecount (BINFO_TYPE (binfo), 0), 0);      expr = build_binary_op (PLUS_EXPR, vlist, expr);      expr = build_modify_expr (vlist, NOP_EXPR, expr);      expand_expr_stmt (expr);    }}/* Subroutine of `expand_aggr_vbase_init'.   BINFO is the binfo of the type that is being initialized.   INIT_LIST is the list of initializers for the virtual baseclass.  */static voidexpand_aggr_vbase_init_1 (binfo, exp, addr, init_list)     tree binfo, exp, addr, init_list;{  tree init = purpose_member (binfo, init_list);  tree ref = build_indirect_ref (addr, NULL_PTR);  expand_start_target_temps ();  if (init)    init = TREE_VALUE (init);  /* Call constructors, but don't set up vtables.  */  expand_aggr_init_1 (binfo, exp, ref, init, LOOKUP_COMPLAIN);  expand_end_target_temps ();  free_temp_slots ();}/* Construct the virtual base-classes of THIS_REF (whose address is   THIS_PTR).  The object has the indicated TYPE.  The construction   actually takes place only if FLAG is non-zero.  INIT_LIST is list   of initialization for constructor to perform.  */static voidconstruct_virtual_bases (type, this_ref, this_ptr, init_list, flag)     tree type;     tree this_ref;     tree this_ptr;     tree init_list;     tree flag;{  tree vbases;  tree result;  tree vlist = NULL_TREE;  /* If there are no virtual baseclasses, we shouldn't even be here.  */  my_friendly_assert (TYPE_USES_VIRTUAL_BASECLASSES (type), 19990621);  /* First set the pointers in our object that tell us where to find     our virtual baseclasses.  */  expand_start_cond (flag, 0);  if (TYPE_USES_PVBASES (type))    {      init_vlist (type);      vlist = lookup_name (vlist_identifier, 0);    }  result = init_vbase_pointers (type, this_ptr);  if (result)    expand_expr_stmt (build_compound_expr (result));  expand_end_cond ();  /* Now, run through the baseclasses, initializing each.  */   for (vbases = CLASSTYPE_VBASECLASSES (type); vbases;       vbases = TREE_CHAIN (vbases))    {      tree tmp = purpose_member (vbases, result);            /* If there are virtual base classes with destructors, we need to	 emit cleanups to destroy them if an exception is thrown during	 the construction process.  These exception regions (i.e., the	 period during which the cleanups must occur) begin from the time	 the construction is complete to the end of the function.  If we	 create a conditional block in which to initialize the	 base-classes, then the cleanup region for the virtual base begins	 inside a block, and ends outside of that block.  This situation	 confuses the sjlj exception-handling code.  Therefore, we do not	 create a single conditional block, but one for each	 initialization.  (That way the cleanup regions always begin	 in the outer block.)  We trust the back-end to figure out	 that the FLAG will not change across initializations, and	 avoid doing multiple tests.  */      expand_start_cond (flag, 0);      expand_aggr_vbase_init_1 (vbases, this_ref,				TREE_OPERAND (TREE_VALUE (tmp), 0),				init_list);      expand_end_cond ();            expand_cleanup_for_base (vbases, vlist, flag);    }}/* Find the context in which this FIELD can be initialized.  */static treeinitializing_context (field)     tree field;{  tree t = DECL_CONTEXT (field);  /* Anonymous union members can be initialized in the first enclosing     non-anonymous union context.  */  while (t && ANON_UNION_TYPE_P (t))    t = TYPE_CONTEXT (t);  return t;}/* Function to give error message if member initialization specification   is erroneous.  FIELD is the member we decided to initialize.   TYPE is the type for which the initialization is being performed.   FIELD must be a member of TYPE.      MEMBER_NAME is the name of the member.  */static intmember_init_ok_or_else (field, type, member_name)     tree field;     tree type;     const char *member_name;{  if (field == error_mark_node)    return 0;  if (field == NULL_TREE || initializing_context (field) != type)    {      cp_error ("class `%T' does not have any field named `%s'", type,		member_name);      return 0;    }  if (TREE_STATIC (field))    {      cp_error ("field `%#D' is static; only point of initialization is its declaration",		field);      return 0;    }  return 1;}/* If NAME is a viable field name for the aggregate DECL,   and PARMS is a viable parameter list, then expand an _EXPR   which describes this initialization.   Note that we do not need to chase through the class's base classes   to look for NAME, because if it's in that list, it will be handled   by the constructor for that base class.   We do not yet have a fixed-point finder to instantiate types   being fed to overloaded constructors.  If there is a unique   constructor, then argument types can be got from that one.   If INIT is non-NULL, then it the initialization should   be placed in `current_base_init_list', where it will be processed   by `emit_base_init'.  */voidexpand_member_init (exp, name, init)     tree exp, name, init;{  tree basetype = NULL_TREE, field;  tree type;  if (exp == NULL_TREE)    return;			/* complain about this later */  type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));  if (name && TREE_CODE (name) == TYPE_DECL)    {      basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));      name = DECL_NAME (name);    }  if (name == NULL_TREE && IS_AGGR_TYPE (type))    switch (CLASSTYPE_N_BASECLASSES (type))      {      case 0:	error ("base class initializer specified, but no base class to initialize");	return;      case 1:	basetype = TYPE_BINFO_BASETYPE (type, 0);	break;      default:	error ("initializer for unnamed base class ambiguous");	cp_error ("(type `%T' uses multiple inheritance)", type);	return;      }  my_friendly_assert (init != NULL_TREE, 0);  /* The grammar should not allow fields which have names that are     TYPENAMEs.  Therefore, if the field has a non-NULL TREE_TYPE, we     may assume that this is an attempt to initialize a base class     member of the current type.  Otherwise, it is an attempt to     initialize a member field.  */  if (init == void_type_node)    init = NULL_TREE;  if (name == NULL_TREE || basetype)    {      tree base_init;      if (name == NULL_TREE)	{#if 0	  if (basetype)	    name = TYPE_IDENTIFIER (basetype);	  else	    {	      error ("no base class to initialize");	      return;	    }#endif	}      else if (basetype != type	       && ! current_template_parms	       && ! vec_binfo_member (basetype,				      TYPE_BINFO_BASETYPES (type))	       && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type)))	{	  if (IDENTIFIER_CLASS_VALUE (name))	    goto try_member;	  if (TYPE_USES_VIRTUAL_BASECLASSES (type))	    cp_error ("type `%T' is not an immediate or virtual basetype for `%T'",		      basetype, type);	  else	    cp_error ("type `%T' is not an immediate basetype for `%T'",		      basetype, type);	  return;	}      if (purpose_member (basetype, current_base_init_list))	{	  cp_error ("base class `%T' already initialized", basetype);	  return;	}      if (warn_reorder && current_member_init_list)	{	  cp_warning ("base initializer for `%T'", basetype);	  warning ("   will be re-ordered to precede member initializations");	}      base_init = build_tree_list (basetype, init);      current_base_init_list = chainon (current_base_init_list, base_init);    }  else    {      tree member_init;    try_member:      field = lookup_field (type, name, 1, 0);      if (! member_init_ok_or_else (field, type, IDENTIFIER_POINTER (name)))	return;      if (purpose_member (name, current_member_init_list))	{	  cp_error ("field `%D' already initialized", field);	  return;	}      member_init = build_tree_list (name, init);      current_member_init_list = chainon (current_member_init_list, member_init);    }}/* This is like `expand_member_init', only it stores one aggregate   value into another.   INIT comes in two flavors: it is either a value which   is to be stored in EXP, or it is a parameter list   to go to a constructor, which will operate on EXP.   If INIT is not a parameter list for a constructor, then set   LOOKUP_ONLYCONVERTING.   If FLAGS is LOOKUP_ONLYCONVERTING then it is the = init form of   the initializer, if FLAGS is 0, then it is the (init) form.   If `init' is a CONSTRUCTOR, then we emit a warning message,   explaining that such initializations are invalid.   ALIAS_THIS is nonzero iff we are initializing something which is   essentially an alias for current_class_ref.  In this case, the base   constructor may move it on us, and we must keep track of such   deviations.   If INIT resolves to a CALL_EXPR which happens to return   something of the type we are looking for, then we know   that we can safely use that call to perform the   initialization.   The virtual function table pointer cannot be set up here, because   we do not really know its type.   Virtual baseclass pointers are also set up here.   This never calls operator=().   When initializing, nothing is CONST.   A default copy constructor may have to be used to perform the   initialization.   A constructor or a conversion operator may have to be used to   perform the initialization, but not both, as it would be ambiguous.  */voidexpand_aggr_init (exp, init, flags)     tree exp, init;     int flags;{  tree type = TREE_TYPE (exp);  int was_const = TREE_READONLY (exp);  int was_volatile = TREE_THIS_VOLATILE (exp);  if (init == error_mark_node)    return;  TREE_READONLY (exp) = 0;  TREE_THIS_VOLATILE (exp) = 0;  if (init && TREE_CODE (init) != TREE_LIST)    flags |= LOOKUP_ONLYCONVERTING;  if (TREE_CODE (type) == ARRAY_TYPE)    {      /* Must arrange to initialize each element of EXP	 from elements of INIT.  */      tree itype = init ? TREE_TYPE (init) : NULL_TREE;      if (CP_TYPE_QUALS (type) != TYPE_UNQUALIFIED)	{	  TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);	  if (init)	    TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);	}      if (init && TREE_TYPE (init) == NULL_TREE)	{	  /* Handle bad initializers like:	     class COMPLEX {	     public:	       double re, im;	       COMPLEX(double r = 0.0, double i = 0.0) {re = r; im = i;};	       ~COMPLEX() {};	     };	     int main(int argc, char **argv) {	       COMPLEX zees(1.0, 0.0)[10];	     }	  */	  error ("bad array initializer");	  return;	}      expand_vec_init (exp, exp, array_type_nelts (type), init,		       init && same_type_p (TREE_TYPE (init),					    TREE_TYPE (exp)));      TREE_READONLY (exp) = was_const;      TREE_THIS_VOLATILE (exp) = was_volatile;      TREE_TYPE (exp) = type;      if (init)	TREE_TYPE (init) = itype;      return;    }  if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)    /* just know that we've seen something for this node */    TREE_USED (exp) = 1;#if 0  /* If initializing from a GNU C CONSTRUCTOR, consider the elts in the     constructor as parameters to an implicit GNU C++ constructor.  */  if (init && TREE_CODE (init) == CONSTRUCTOR      && TYPE_HAS_CONSTRUCTOR (type)      && TREE_TYPE (init) == type)    init = CONSTRUCTOR_ELTS (init);#endif  TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);  expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,		      init, LOOKUP_NORMAL|flags);  TREE_TYPE (exp) = type;  TREE_READONLY (exp) = was_const;  TREE_THIS_VOLATILE (exp) = was_volatile;}static treeno_vlist_base_init (rval, exp, init, binfo, flags)     tree rval, exp, init, binfo;     int flags;{  tree nrval, func, parms;  /* Obtain the vlist-expecting ctor.  */  func = rval;  my_friendly_assert (TREE_CODE (func) == CALL_EXPR, 20000131);  func = TREE_OPERAND (func, 0);  my_friendly_assert (TREE_CODE (func) == ADDR_EXPR, 20000132);  func = TREE_OPERAND (func, 0);  my_friendly_assert (TREE_CODE (func) == FUNCTION_DECL, 20000133);    /* If we have already seen a definition for the wrapped function,     we don't need to declare it weak. Also, declare_weak will complain     if we do.  */  if (!TREE_ASM_WRITTEN (func))    declare_weak (func);  if (init == NULL_TREE      || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))    {      parms = init;      if (parms)	init = TREE_VALUE (parms);    }  else    parms = build_expr_list (NULL_TREE, init);  flags &= ~LOOKUP_HAS_VLIST;  parms = expr_tree_cons (NULL_TREE, integer_zero_node, parms);  flags |= LOOKUP_HAS_IN_CHARGE;    nrval = build_method_call (exp, ctor_identifier,			     parms, binfo, flags);  func = build (NE_EXPR, boolean_type_node,		func, null_pointer_node);  nrval = build (COND_EXPR, void_type_node,		 func, rval, nrval);  return nrval;} static voidexpand_default_init (binfo, true_exp, exp, init, flags)     tree binfo;     tree true_exp, exp;

⌨️ 快捷键说明

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