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

📄 gc.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
  type = TREE_TYPE (type);  if (!TYPE_VIRTUAL_P (type) || CLASSTYPE_VFIELD (type) == NULL_TREE)    return exp;  vptr = fold (size_binop (PLUS_EXPR, 	   size_binop (FLOOR_DIV_EXPR,   	     DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (type)),	     size_int (BITS_PER_UNIT)), 	   exp));   vptr = build1 (INDIRECT_REF, build_pointer_type (vtable_entry_type), vptr);  if (flag_vtable_thunks)    offset = build_array_ref (vptr, integer_zero_node);  else    offset = build_component_ref (build_array_ref (vptr, integer_zero_node),				  delta_identifier,				  NULL_TREE, 0);  type = build_type_variant (ptr_type_node, TREE_READONLY (exp),			     TREE_THIS_VOLATILE (exp));  return build (PLUS_EXPR, type, exp,		convert (ptrdiff_type_node, offset));}/* Return the type_info node associated with the expression EXP.  If EXP is   a reference to a polymorphic class, return the dynamic type; otherwise   return the static type of the expression.  */treebuild_typeid (exp)     tree exp;{  tree type;  if (!flag_rtti)    cp_error ("cannot take typeid of object when -frtti is not specified");  if (exp == error_mark_node)    return error_mark_node;  type = TREE_TYPE (exp);  /* Strip top-level cv-qualifiers.  */  type = TYPE_MAIN_VARIANT (type);  /* if b is an instance of B, typeid(b) == typeid(B).  Do this before     reference trickiness.  */  if (TREE_CODE (exp) == VAR_DECL && TREE_CODE (type) == RECORD_TYPE)    return get_typeid (type);  /* peel back references, so they match. */  if (TREE_CODE (type) == REFERENCE_TYPE)    type = TREE_TYPE (type);  /* Peel off cv qualifiers. */  type = TYPE_MAIN_VARIANT (type);  /* Apply trivial conversion T -> T& for dereferenced ptrs.  */  if (TREE_CODE (type) == RECORD_TYPE)    type = build_reference_type (type);  /* If exp is a reference to polymorphic type, get the real type_info.  */  if (TREE_CODE (type) == REFERENCE_TYPE && TYPE_VIRTUAL_P (TREE_TYPE (type)))    {      /* build reference to type_info from vtable.  */      tree t;      if (flag_vtable_thunks)	t = build_vfn_ref ((tree *) NULL_TREE, exp, integer_one_node);      else	t = build_vfn_ref ((tree *) NULL_TREE, exp, integer_zero_node);      TREE_TYPE (t) = build_pointer_type (__class_desc_type_node);      t = build_indirect_ref (t, NULL);      return t;    }  /* otherwise return the type_info for the static type of the expr.  */  return get_typeid (type);}/* Return the type_info object for TYPE, creating it if necessary.  */treeget_typeid (type)     tree type;{  tree t, td;  if (type == error_mark_node)    return error_mark_node;    /* Is it useful (and/or correct) to have different typeids for `T &'     and `T'?  */  if (TREE_CODE (type) == REFERENCE_TYPE)    type = TREE_TYPE (type);  td = build_t_desc (type, 1);  if (td == error_mark_node)    return error_mark_node;  t = TREE_OPERAND (td, 0);  return t;}/* Get a bad_cast node for the program to throw...   See libstdc++::exception{,.cc} for __bad_cast_object */treeget_bad_cast_node (){  static tree t;  if (t == NULL_TREE      && (t = lookup_name (get_identifier ("__bad_cast_object"), 0))         == NULL_TREE)    {      error ("you must #include <typeinfo>");      return error_mark_node;    }  return t;}/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working   paper.  */treebuild_dynamic_cast (type, expr)     tree type, expr;{  enum tree_code tc = TREE_CODE (type);  tree exprtype = TREE_TYPE (expr);  enum tree_code ec = TREE_CODE (exprtype);  tree retval;  if (type == error_mark_node || expr == error_mark_node)    return error_mark_node;    switch (tc)    {    case POINTER_TYPE:      if (ec == REFERENCE_TYPE)	{	  expr = convert_from_reference (expr);	  exprtype = TREE_TYPE (expr);	  ec = TREE_CODE (exprtype);	}      if (ec != POINTER_TYPE)	goto fail;      if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)	goto fail;      if (TYPE_SIZE (TREE_TYPE (exprtype)) == 0)	goto fail;      if (TREE_READONLY (TREE_TYPE (exprtype)) &&	  ! TYPE_READONLY (TREE_TYPE (type)))	goto fail;      if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)	break;      /* else fall through */    case REFERENCE_TYPE:      if (TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE	  && TYPE_SIZE (TREE_TYPE (type)) != NULL_TREE)	break;      /* else fall through */    default:      goto fail;    }  /* Apply trivial conversion T -> T& for dereferenced ptrs.  */  if (ec == RECORD_TYPE)    {      exprtype = build_type_variant (exprtype, TREE_READONLY (expr),				     TREE_THIS_VOLATILE (expr));      exprtype = build_reference_type (exprtype);      expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,				   LOOKUP_NORMAL, NULL_TREE);      ec = REFERENCE_TYPE;    }  if (tc == REFERENCE_TYPE)    {      if (ec != REFERENCE_TYPE)	goto fail;      if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE)	goto fail;      if (TYPE_SIZE (TREE_TYPE (exprtype)) == 0)	goto fail;    }  /* If *type is an unambiguous accessible base class of *exprtype,     convert statically.  */  {    int distance;    tree path;    distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,				  &path);    if (distance >= 0)      return build_vbase_path (PLUS_EXPR, type, expr, path, 0);  }  /* Otherwise *exprtype must be a polymorphic class (have a vtbl).  */  if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype)))    {      /* if TYPE is `void *', return pointer to complete object.  */      if (tc == POINTER_TYPE	  && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)	{	  /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b.  */	  if (TREE_CODE (expr) == ADDR_EXPR	      && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE)	    return build1 (NOP_EXPR, type, expr);	  return build_headof (expr);	}      else	{	  tree retval;          tree result, td1, td2, elems, tmp1, expr1; 	  /* If we got here, we can't convert statically.  Therefore,	     dynamic_cast<D&>(b) (b an object) cannot succeed.  */	  if (ec == REFERENCE_TYPE)	    {	      if (TREE_CODE (expr) == VAR_DECL		  && TREE_CODE (TREE_TYPE (expr)) == RECORD_TYPE)		{		  cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",			      expr, type);		  return build_throw (get_bad_cast_node ());		}	    }	  /* Ditto for dynamic_cast<D*>(&b).  */	  else if (TREE_CODE (expr) == ADDR_EXPR)	    {	      tree op = TREE_OPERAND (expr, 0);	      if (TREE_CODE (op) == VAR_DECL		  && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)		{		  cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",			      expr, type);		  retval = build_int_2 (0, 0); 		  TREE_TYPE (retval) = type; 		  return retval;		}	    }	  expr1 = expr;	  if (tc == REFERENCE_TYPE)	    expr1 = build_unary_op (ADDR_EXPR, expr1, 0);	  /* Build run-time conversion.  */	  expr1 = build_headof (expr1);	  if (ec == POINTER_TYPE)	    td1 = build_typeid (build_indirect_ref (expr, NULL_PTR));	  else	    td1 = build_typeid (expr);	  	  if (tc == POINTER_TYPE)	    td2 = get_typeid (TREE_TYPE (type));	  else	    td2 = get_typeid (type);          elems = tree_cons (NULL_TREE, td2,            tree_cons (NULL_TREE, build_int_2 (1, 0),	      tree_cons (NULL_TREE, expr1, NULL_TREE)));          result = build_method_call (td1,            get_identifier ("__rtti_match"), elems, NULL_TREE, LOOKUP_NORMAL);	  if (tc == REFERENCE_TYPE)	    {	      expr1 = build_throw (get_bad_cast_node ());	      expr1 = build_compound_expr (tree_cons (NULL_TREE, expr1,						      build_tree_list (NULL_TREE, convert (type, integer_zero_node))));	      TREE_TYPE (expr1) = type;	      return build (COND_EXPR, type, result, result, expr1);	    }	  /* Now back to the type we want from a void*. */	  result = convert (type, result);          return result;	}    } fail:  cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",	    expr, exprtype, type);  return error_mark_node;}/* Build and initialize various sorts of descriptors.  Every descriptor   node has a name associated with it (the name created by mangling).   For this reason, we use the identifier as our access to the __*_desc   nodes, instead of sticking them directly in the types.  Otherwise we   would burden all built-in types (and pointer types) with slots that   we don't necessarily want to use.   For each descriptor we build, we build a variable that contains   the descriptor's information.  When we need this info at runtime,   all we need is access to these variables.   Note: these constructors always return the address of the descriptor   info, since that is simplest for their mutual interaction.  */static treebuild_generic_desc (tdecl, type, elems)     tree tdecl;     tree type;     tree elems;{  tree init = elems;  int toplev = global_bindings_p ();  TREE_CONSTANT (init) = 1;  TREE_STATIC (init) = 1;  TREE_READONLY (init) = 1;  TREE_TYPE (tdecl) = type;  DECL_INITIAL (tdecl) = init;  TREE_STATIC (tdecl) = 1;  DECL_SIZE (tdecl) = NULL_TREE;  layout_decl (tdecl, 0);  if (! toplev)    push_to_top_level ();  cp_finish_decl (tdecl, init, NULL_TREE, 0, 0);  if (! toplev)    pop_from_top_level ();  if (! TREE_USED (tdecl))    {      assemble_external (tdecl);      TREE_USED (tdecl) = 1;    }  return IDENTIFIER_AS_DESC (DECL_NAME (tdecl));}/* Build an initializer for a __bltn_desc node.  */static treebuild_bltn_desc (tdecl, type)     tree tdecl;     tree type;{  tree elems, t;  if (type == boolean_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_BOOL"),		      0, 0);  else if (type == char_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_CHAR"),		      0, 0);  else if (type == short_integer_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_SHORT"),		      0, 0);  else if (type == integer_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_INT"),		      0, 0);  else if (type == long_integer_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_LONG"),		      0, 0);  else if (type == long_long_integer_type_node)    t = lookup_field (__bltn_desc_type_node, 		      get_identifier("_RTTI_BI_LONGLONG"), 0, 0);  else if (type == float_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_FLOAT"),		      0, 0);  else if (type == double_type_node)    t = lookup_field (__bltn_desc_type_node, 		      get_identifier("_RTTI_BI_DOUBLE"), 0, 0);  else if (type == long_double_type_node)    t = lookup_field (__bltn_desc_type_node, 		      get_identifier("_RTTI_BI_LDOUBLE"), 0, 0);  else if (type == unsigned_char_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_UCHAR"),		      0, 0);  else if (type == short_unsigned_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_USHORT"),		      0, 0);  else if (type == unsigned_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_UINT"),		      0, 0);  else if (type == long_unsigned_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_ULONG"),		      0, 0);  else if (type == long_long_unsigned_type_node)    t = lookup_field (__bltn_desc_type_node, 		      get_identifier("_RTTI_BI_ULONGLONG"), 0, 0);  else if (type == signed_char_type_node)    t = lookup_field (__bltn_desc_type_node, get_identifier("_RTTI_BI_SCHAR"),

⌨️ 快捷键说明

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