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

📄 init.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
	  t = convert_from_reference (t);	}      return t;    }  if (type == NULL_TREE || ! is_aggr_type (type, 1))    return error_mark_node;  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)    {      /* If the NAME is a TEMPLATE_ID_EXPR, we are looking at	 something like `a.template f<int>' or the like.  For the most	 part, we treat this just like a.f.  We do remember, however,	 the template-id that was used.  */      name = TREE_OPERAND (orig_name, 0);      if (TREE_CODE (name) == LOOKUP_EXPR)	/* This can happen during tsubst'ing.  */	name = TREE_OPERAND (name, 0);      my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);    }  if (TREE_CODE (name) == BIT_NOT_EXPR)    {      if (! check_dtor_name (type, name))	cp_error ("qualified type `%T' does not match destructor name `~%T'",		  type, TREE_OPERAND (name, 0));      name = dtor_identifier;    }#if 0  /* I think this is wrong, but the draft is unclear.  --jason 6/15/98 */  else if (name == constructor_name_full (type)	   || name == constructor_name (type))    name = ctor_identifier;#endif  if (TYPE_SIZE (complete_type (type)) == 0      && !TYPE_BEING_DEFINED (type))    {      cp_error ("incomplete type `%T' does not have member `%D'", type,		name);      return error_mark_node;    }  decl = maybe_dummy_object (type, &basebinfo);  member = lookup_member (basebinfo, name, 1, 0);  if (member == error_mark_node)    return error_mark_node;  /* A lot of this logic is now handled in lookup_field and     lookup_fnfield.  */  if (member && BASELINK_P (member))    {      /* Go from the TREE_BASELINK to the member function info.  */      tree fnfields = member;      t = TREE_VALUE (fnfields);      if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)	{	  /* The FNFIELDS are going to contain functions that aren't	     necessarily templates, and templates that don't	     necessarily match the explicit template parameters.  We	     save all the functions, and the explicit parameters, and	     then figure out exactly what to instantiate with what	     arguments in instantiate_type.  */	  if (TREE_CODE (t) != OVERLOAD)	    /* The code in instantiate_type which will process this	       expects to encounter OVERLOADs, not raw functions.  */	    t = ovl_cons (t, NULL_TREE);	  	  return build (OFFSET_REF, 			unknown_type_node,			decl,			build (TEMPLATE_ID_EXPR, 			       TREE_TYPE (t),			       t,			       TREE_OPERAND (orig_name, 1)));	}      if (!really_overloaded_fn (t))	{	  /* Get rid of a potential OVERLOAD around it */	  t = OVL_CURRENT (t);	  /* unique functions are handled easily.  */	  basebinfo = TREE_PURPOSE (fnfields);	  if (!enforce_access (basebinfo, t))	    return error_mark_node;	  mark_used (t);	  if (DECL_STATIC_FUNCTION_P (t))	    return t;	  return build (OFFSET_REF, TREE_TYPE (t), decl, t);	}      /* FNFIELDS is most likely allocated on the search_obstack,	 which will go away after this class scope.  If we need	 to save this value for later (i.e. for use as an initializer	 for a static variable), then do so here.	 ??? The smart thing to do for the case of saving initializers	 is to resolve them before we're done with this scope.  */      if (!TREE_PERMANENT (fnfields)	  && ! allocation_temporary_p ())	fnfields = copy_list (fnfields);      TREE_TYPE (fnfields) = unknown_type_node;      return build (OFFSET_REF, unknown_type_node, decl, fnfields);    }  t = member;  if (t == NULL_TREE)    {      cp_error ("`%D' is not a member of type `%T'", name, type);      return error_mark_node;    }  if (TREE_CODE (t) == TYPE_DECL)    {      TREE_USED (t) = 1;      return t;    }  /* static class members and class-specific enum     values can be returned without further ado.  */  if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL)    {      mark_used (t);      return convert_from_reference (t);    }  if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t))    {      cp_error ("illegal pointer to bit field `%D'", t);      return error_mark_node;    }  /* static class functions too.  */  if (TREE_CODE (t) == FUNCTION_DECL      && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)    my_friendly_abort (53);  /* In member functions, the form `type::name' is no longer     equivalent to `this->type::name', at least not until     resolve_offset_ref.  */  return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t);}/* If a OFFSET_REF made it through to here, then it did   not have its address taken.  */treeresolve_offset_ref (exp)     tree exp;{  tree type = TREE_TYPE (exp);  tree base = NULL_TREE;  tree member;  tree basetype, addr;  if (TREE_CODE (exp) == OFFSET_REF)    {      member = TREE_OPERAND (exp, 1);      base = TREE_OPERAND (exp, 0);    }  else    {      my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214);      if (TYPE_OFFSET_BASETYPE (type) != current_class_type)	{	  error ("object missing in use of pointer-to-member construct");	  return error_mark_node;	}      member = exp;      type = TREE_TYPE (type);      base = current_class_ref;    }  if (BASELINK_P (member))    {      cp_pedwarn ("assuming & on overloaded member function");      return build_unary_op (ADDR_EXPR, exp, 0);    }  if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)    {      cp_pedwarn ("assuming & on `%E'", member);      return build_unary_op (ADDR_EXPR, exp, 0);    }  if ((TREE_CODE (member) == VAR_DECL       && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member))       && ! TYPE_PTRMEM_P (TREE_TYPE (member)))      || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE)    {      /* These were static members.  */      if (mark_addressable (member) == 0)	return error_mark_node;      return member;    }  if (TREE_CODE (TREE_TYPE (member)) == POINTER_TYPE      && TREE_CODE (TREE_TYPE (TREE_TYPE (member))) == METHOD_TYPE)    return member;  /* Syntax error can cause a member which should     have been seen as static to be grok'd as non-static.  */  if (TREE_CODE (member) == FIELD_DECL && current_class_ref == NULL_TREE)    {      if (TREE_ADDRESSABLE (member) == 0)	{	  cp_error_at ("member `%D' is non-static but referenced as a static member",		       member);	  error ("at this point in file");	  TREE_ADDRESSABLE (member) = 1;	}      return error_mark_node;    }  /* The first case is really just a reference to a member of `this'.  */  if (TREE_CODE (member) == FIELD_DECL      && (base == current_class_ref || is_dummy_object (base)))    {      tree basetype_path;      tree expr;      if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)	basetype = TYPE_OFFSET_BASETYPE (type);      else	basetype = DECL_CONTEXT (member);      base = current_class_ptr;            if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0)	{	  error_not_base_type (basetype, TREE_TYPE (TREE_TYPE (base)));	  return error_mark_node;	}      /* Kludge: we need to use basetype_path now, because	 convert_pointer_to will bash it.  */      enforce_access (basetype_path, member);      addr = convert_pointer_to (basetype, base);      /* Even in the case of illegal access, we form the	 COMPONENT_REF; that will allow better error recovery than	 just feeding back error_mark_node.  */      expr = build (COMPONENT_REF, TREE_TYPE (member),		    build_indirect_ref (addr, NULL_PTR), member);      return convert_from_reference (expr);    }  /* Ensure that we have an object.  */  if (is_dummy_object (base))    addr = error_mark_node;  else    /* If this is a reference to a member function, then return the       address of the member function (which may involve going       through the object's vtable), otherwise, return an expression       for the dereferenced pointer-to-member construct.  */    addr = build_unary_op (ADDR_EXPR, base, 0);  if (TYPE_PTRMEM_P (TREE_TYPE (member)))    {      if (addr == error_mark_node)	{	  cp_error ("object missing in `%E'", exp);	  return error_mark_node;	}      basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (member)));      addr = convert_pointer_to (basetype, addr);      member = cp_convert (ptrdiff_type_node, member);            /* Pointer to data members are offset by one, so that a null	 pointer with a real value of 0 is distinguishable from an	 offset of the first member of a structure.  */      member = build_binary_op (MINUS_EXPR, member,				cp_convert (ptrdiff_type_node, integer_one_node));      return build1 (INDIRECT_REF, type,		     build (PLUS_EXPR, build_pointer_type (type),			    addr, member));    }  else if (TYPE_PTRMEMFUNC_P (TREE_TYPE (member)))    {      return get_member_function_from_ptrfunc (&addr, member);    }  my_friendly_abort (56);  /* NOTREACHED */  return NULL_TREE;}/* Return either DECL or its known constant value (if it has one).  */treedecl_constant_value (decl)     tree decl;{  if (! TREE_THIS_VOLATILE (decl)      && DECL_INITIAL (decl)      && DECL_INITIAL (decl) != error_mark_node      /* This is invalid if initial value is not constant.	 If it has either a function call, a memory reference,	 or a variable, then re-evaluating it could give different results.  */      && TREE_CONSTANT (DECL_INITIAL (decl))      /* Check for cases where this is sub-optimal, even though valid.  */      && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)    return DECL_INITIAL (decl);  return decl;}/* Common subroutines of build_new and build_vec_delete.  *//* Call the global __builtin_delete to delete ADDR.  */static treebuild_builtin_delete_call (addr)     tree addr;{  mark_used (global_delete_fndecl);  return build_call (global_delete_fndecl, 		     void_type_node, build_expr_list (NULL_TREE, addr));}/* Generate a C++ "new" expression. DECL is either a TREE_LIST   (which needs to go through some sort of groktypename) or it   is the name of the class we are newing. INIT is an initialization value.   It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces.   If INIT is void_type_node, it means do *not* call a constructor   for this instance.   For types with constructors, the data returned is initialized   by the appropriate constructor.   Whether the type has a constructor or not, if it has a pointer   to a virtual function table, then that pointer is set up   here.   Unless I am mistaken, a call to new () will return initialized   data regardless of whether the constructor itself is private or   not.  NOPE; new fails if the constructor is private (jcm).   Note that build_new does nothing to assure that any special   alignment requirements of the type are met.  Rather, it leaves   it up to malloc to do the right thing.  Otherwise, folding to   the right alignment cal cause problems if the user tries to later   free the memory returned by `new'.   PLACEMENT is the `placement' list for user-defined operator new ().  */extern int flag_check_new;treebuild_new (placement, decl, init, use_global_new)     tree placement;     tree decl, init;     int use_global_new;{  tree type, rval;  tree nelts = NULL_TREE, t;  int has_array = 0;  tree pending_sizes = NULL_TREE;  if (decl == error_mark_node)    return error_mark_node;  if (TREE_CODE (decl) == TREE_LIST)    {      tree absdcl = TREE_VALUE (decl);      tree last_absdcl = NULL_TREE;      int old_immediate_size_expand = 0;      if (current_function_decl	  && DECL_CONSTRUCTOR_P (current_function_decl))	{	  old_immediate_size_expand = immediate_size_expand;	  immediate_size_expand = 0;	}      nelts = integer_one_node;      if (absdcl && TREE_CODE (absdcl) == CALL_EXPR)	my_friendly_abort (215);      while (absdcl && TREE_CODE (absdcl) == INDIRECT_REF)	{	  last_absdcl = absdcl;	  absdcl = TREE_OPERAND (absdcl, 0);	}      if (absdcl && TREE_CODE (absdcl) == ARRAY_REF)	{	  /* probably meant to be a vec new */	  tree this_nelts;	  while (TREE_OPERAND (absdcl, 0)		 && TREE_CODE (TREE_OPERAND (absdcl, 0)) == ARRAY_REF)	    {	      last_absdcl = absdcl;	      absdcl = TREE_OPERAND (absdcl, 0);	    }	  has_array = 1;	  this_nelts = TREE_OPERAND (absdcl, 1);	  if (this_nelts != error_mark_node)	    {	      if (this_nelts == NULL_TREE)		error ("new of array type fails to specify size");	      else if (processing_template_decl)		{		  nelts = this_nelts;		  absdcl = TREE_OPERAND (absdcl, 0);		}	      else		{		  int flags = pedantic ? WANT_INT : (WANT_INT | WANT_ENUM);		  if (build_expr_type_conversion (flags, this_nelts, 0)		      == NULL_TREE)		    pedwarn ("size in array new must have integral type");		  this_nelts = save_expr (cp_convert (sizetype, this_nelts));		  absdcl = TREE_OPERAND (absdcl, 0);	          if (this_nelts == integer_zero_node)		    {		      warning ("zero size array reserves no space");		      nelts = integer_zero_node;		    }		  else		

⌨️ 快捷键说明

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