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

📄 rtti.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
{  tree name_string;  tree fn, tmp;  const char *name;  int i = CLASSTYPE_N_BASECLASSES (type);  int base_cnt = 0;  tree binfos = TYPE_BINFO_BASETYPES (type);#if 0  /* See code below that used these.  */  tree vb = CLASSTYPE_VBASECLASSES (type);  int n_base = i;#endif  tree base, elems, access, offset, isvir;  tree elt, elts = NULL_TREE;  static tree base_info_type_node;  if (base_info_type_node == NULL_TREE)    {      tree fields [4];      /* A reasonably close approximation of __class_type_info::base_info */      push_obstacks (&permanent_obstack, &permanent_obstack);      base_info_type_node = make_lang_type (RECORD_TYPE);      /* Actually const __user_type_info * */      fields [0] = build_lang_field_decl	(FIELD_DECL, NULL_TREE,	 build_pointer_type (build_qualified_type			     (type_info_type_node,			      TYPE_QUAL_CONST)));      fields [1] = build_lang_field_decl	(FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);      DECL_BIT_FIELD (fields[1]) = 1;      DECL_FIELD_SIZE (fields[1]) = 29;      fields [2] = build_lang_field_decl	(FIELD_DECL, NULL_TREE, boolean_type_node);      DECL_BIT_FIELD (fields[2]) = 1;      DECL_FIELD_SIZE (fields[2]) = 1;      /* Actually enum access */      fields [3] = build_lang_field_decl	(FIELD_DECL, NULL_TREE, integer_type_node);      DECL_BIT_FIELD (fields[3]) = 1;      DECL_FIELD_SIZE (fields[3]) = 2;      finish_builtin_type (base_info_type_node, "__base_info", fields,			   3, ptr_type_node);      pop_obstacks ();    }  while (--i >= 0)    {      tree binfo = TREE_VEC_ELT (binfos, i);      expand_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));      base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));      if (TREE_VIA_VIRTUAL (binfo))	{	  tree t = BINFO_TYPE (binfo);	  const char *name;	  tree field;	  FORMAT_VBASE_NAME (name, t);	  field = lookup_field (type, get_identifier (name), 0, 0);	  offset = size_binop (FLOOR_DIV_EXPR, 		DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT));	  offset = convert (sizetype, offset);	}      else	offset = BINFO_OFFSET (binfo);      if (TREE_VIA_PUBLIC (binfo))        access = access_public_node;      else if (TREE_VIA_PROTECTED (binfo))	access = access_protected_node;      else	access = access_private_node;      if (TREE_VIA_VIRTUAL (binfo))	isvir = boolean_true_node;      else	isvir = boolean_false_node;      elt = build	(CONSTRUCTOR, base_info_type_node, NULL_TREE, tree_cons	 (NULL_TREE, base, tree_cons	  (NULL_TREE, offset, tree_cons	   (NULL_TREE, isvir, tree_cons	    (NULL_TREE, access, NULL_TREE)))));      TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;      elts = expr_tree_cons (NULL_TREE, elt, elts);      base_cnt++;    }#if 0  i = n_base;  while (vb)    {      tree b;      access = access_public_node;      while (--i >= 0)	{	  b = TREE_VEC_ELT (binfos, i);	  if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))	    {	      if (TREE_VIA_PUBLIC (b))		access = access_public_node;	      else if (TREE_VIA_PROTECTED (b))		access = access_protected_node;	      else		access = access_private_node;	      break;	    }	}      base = build_t_desc (BINFO_TYPE (vb), 1);      offset = BINFO_OFFSET (vb);      isvir = build_int_2 (1, 0);      base_list = expr_tree_cons (NULL_TREE, base, base_list);      isvir_list = expr_tree_cons (NULL_TREE, isvir, isvir_list);      acc_list = expr_tree_cons (NULL_TREE, access, acc_list);      off_list = expr_tree_cons (NULL_TREE, offset, off_list);      base_cnt++;      vb = TREE_CHAIN (vb);    }#endif  name = build_overload_name (type, 1, 1);  name_string = combine_strings (build_string (strlen (name)+1, name));  {    tree arrtype = build_array_type (base_info_type_node, NULL_TREE);    elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);    TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)      = TREE_STATIC (elts) = 1;    complete_array_type (arrtype, elts, 1);  }  elems = tree_cons    (NULL_TREE, decay_conversion (tdecl), tree_cons     (NULL_TREE, decay_conversion (name_string), tree_cons      (NULL_TREE, decay_conversion (elts), tree_cons       (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),	NULL_TREE))));  fn = get_identifier ("__rtti_class");  if (IDENTIFIER_GLOBAL_VALUE (fn))    fn = IDENTIFIER_GLOBAL_VALUE (fn);  else    {      push_obstacks (&permanent_obstack, &permanent_obstack);      tmp = tree_cons	(NULL_TREE, ptr_type_node, tree_cons	 (NULL_TREE, const_string_type_node, tree_cons	  (NULL_TREE, build_pointer_type (base_info_type_node), tree_cons	   (NULL_TREE, sizetype, void_list_node))));      tmp = build_function_type	(void_type_node, tmp);        fn = build_lang_decl (FUNCTION_DECL, fn, tmp);      DECL_EXTERNAL (fn) = 1;      TREE_PUBLIC (fn) = 1;      DECL_ARTIFICIAL (fn) = 1;      pushdecl_top_level (fn);      make_function_rtl (fn);      pop_obstacks ();    }  mark_used (fn);  fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);  expand_expr_stmt (fn);}/* Build an initializer for a __pointer_type_info node.  */static voidexpand_ptr_desc (tdecl, type)     tree tdecl;     tree type;{  tree t, elems, fn;  const char *name = build_overload_name (type, 1, 1);  tree name_string = combine_strings (build_string (strlen (name)+1, name));  type = TREE_TYPE (type);  expand_expr_stmt (get_typeid_1 (type));  t = decay_conversion (get_tinfo_var (type));  elems = tree_cons    (NULL_TREE, decay_conversion (tdecl), tree_cons     (NULL_TREE, decay_conversion (name_string), tree_cons      (NULL_TREE, t, NULL_TREE)));  fn = get_identifier ("__rtti_ptr");  if (IDENTIFIER_GLOBAL_VALUE (fn))    fn = IDENTIFIER_GLOBAL_VALUE (fn);  else    {      tree tmp;      push_obstacks (&permanent_obstack, &permanent_obstack);      tmp = tree_cons	(NULL_TREE, ptr_type_node, tree_cons	 (NULL_TREE, const_string_type_node, tree_cons	  (NULL_TREE, build_pointer_type (type_info_type_node),	   void_list_node)));      tmp = build_function_type	(void_type_node, tmp);        fn = build_lang_decl (FUNCTION_DECL, fn, tmp);      DECL_EXTERNAL (fn) = 1;      TREE_PUBLIC (fn) = 1;      DECL_ARTIFICIAL (fn) = 1;      pushdecl_top_level (fn);      make_function_rtl (fn);      pop_obstacks ();    }  mark_used (fn);  fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);  expand_expr_stmt (fn);}/* Build an initializer for a __attr_type_info node.  */static voidexpand_attr_desc (tdecl, type)     tree tdecl;     tree type;{  tree elems, t, fn;  const char *name = build_overload_name (type, 1, 1);  tree name_string = combine_strings (build_string (strlen (name)+1, name));  tree attrval = build_int_2 (TYPE_QUALS (type), 0);  expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));  t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));  elems = tree_cons    (NULL_TREE, decay_conversion (tdecl), tree_cons     (NULL_TREE, decay_conversion (name_string), tree_cons      (NULL_TREE, attrval, expr_tree_cons (NULL_TREE, t, NULL_TREE))));  fn = get_identifier ("__rtti_attr");  if (IDENTIFIER_GLOBAL_VALUE (fn))    fn = IDENTIFIER_GLOBAL_VALUE (fn);  else    {      tree tmp;      push_obstacks (&permanent_obstack, &permanent_obstack);      tmp = tree_cons	(NULL_TREE, ptr_type_node, tree_cons	 (NULL_TREE, const_string_type_node, tree_cons	  (NULL_TREE, integer_type_node, tree_cons	   (NULL_TREE, build_pointer_type (type_info_type_node),	    void_list_node))));      tmp = build_function_type	(void_type_node, tmp);        fn = build_lang_decl (FUNCTION_DECL, fn, tmp);      DECL_EXTERNAL (fn) = 1;      TREE_PUBLIC (fn) = 1;      DECL_ARTIFICIAL (fn) = 1;      pushdecl_top_level (fn);      make_function_rtl (fn);      pop_obstacks ();    }  mark_used (fn);  fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);  expand_expr_stmt (fn);}/* Build an initializer for a type_info node that just has a name.  */static voidexpand_generic_desc (tdecl, type, fnname)     tree tdecl;     tree type;     const char *fnname;{  const char *name = build_overload_name (type, 1, 1);  tree name_string = combine_strings (build_string (strlen (name)+1, name));  tree elems = tree_cons    (NULL_TREE, decay_conversion (tdecl), tree_cons     (NULL_TREE, decay_conversion (name_string), NULL_TREE));  tree fn = get_identifier (fnname);  if (IDENTIFIER_GLOBAL_VALUE (fn))    fn = IDENTIFIER_GLOBAL_VALUE (fn);  else    {      tree tmp;      push_obstacks (&permanent_obstack, &permanent_obstack);      tmp = tree_cons	(NULL_TREE, ptr_type_node, tree_cons	 (NULL_TREE, const_string_type_node, void_list_node));      tmp = build_function_type (void_type_node, tmp);        fn = build_lang_decl (FUNCTION_DECL, fn, tmp);      DECL_EXTERNAL (fn) = 1;      TREE_PUBLIC (fn) = 1;      DECL_ARTIFICIAL (fn) = 1;      pushdecl_top_level (fn);      make_function_rtl (fn);      pop_obstacks ();    }  mark_used (fn);  fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);  expand_expr_stmt (fn);}/* Generate the code for a type_info initialization function.   Note that we take advantage of the passage   5.2.7  Type identification                               [expr.typeid]      Whether or not the destructor is called for the type_info object at the   end of the program is unspecified.   and don't bother to arrange for these objects to be destroyed.  It   doesn't matter, anyway, since the destructors don't do anything.          This must only be called from toplevel (i.e. from finish_file)!  */voidsynthesize_tinfo_fn (fndecl)     tree fndecl;{  tree type = TREE_TYPE (DECL_NAME (fndecl));  tree tmp, addr, tdecl;  if (at_eof)    {      import_export_decl (fndecl);      if (DECL_REALLY_EXTERN (fndecl))	return;    }  tdecl = get_tinfo_var (type);  DECL_EXTERNAL (tdecl) = 0;  TREE_STATIC (tdecl) = 1;  DECL_COMMON (tdecl) = 1;  TREE_USED (tdecl) = 1;  DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);  cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);  start_function (NULL_TREE, fndecl, NULL_TREE, 1);  store_parm_decls ();  clear_last_expr ();  push_momentary ();  /* If the first word of the array (the vtable) is non-zero, we've already     initialized the object, so don't do it again.  */  addr = decay_conversion (tdecl);  tmp = cp_convert (build_pointer_type (ptr_type_node), addr);  tmp = build_indirect_ref (tmp, 0);  tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node);  expand_start_cond (tmp, 0);  if (TREE_CODE (type) == FUNCTION_TYPE)    expand_generic_desc (tdecl, type, "__rtti_func");  else if (TREE_CODE (type) == ARRAY_TYPE)    expand_generic_desc (tdecl, type, "__rtti_array");  else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)    expand_attr_desc (tdecl, type);  else if (TREE_CODE (type) == POINTER_TYPE)    {      if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)	expand_generic_desc (tdecl, type, "__rtti_ptmd");      else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)	expand_generic_desc (tdecl, type, "__rtti_ptmf");      else	expand_ptr_desc (tdecl, type);    }  else if (TYPE_PTRMEMFUNC_P (type))    expand_generic_desc (tdecl, type, "__rtti_ptmf");  else if (IS_AGGR_TYPE (type))    {      if (CLASSTYPE_N_BASECLASSES (type) == 0)	expand_generic_desc (tdecl, type, "__rtti_user");      else if (! TYPE_USES_COMPLEX_INHERITANCE (type)	       && (TREE_VIA_PUBLIC		   (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))	expand_si_desc (tdecl, type);      else	expand_class_desc (tdecl, type);    }  else if (TREE_CODE (type) == ENUMERAL_TYPE)    expand_generic_desc (tdecl, type, "__rtti_user");  else    my_friendly_abort (252);  expand_end_cond ();  /* OK, now return the type_info object.  */  tmp = cp_convert (build_pointer_type (type_info_type_node), addr);  tmp = build_indirect_ref (tmp, 0);  c_expand_return (tmp);  finish_function (lineno, 0, 0);}

⌨️ 快捷键说明

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