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

📄 method.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
	  cname = TREE_OPERAND (tmp, 0);	  tmp = TREE_OPERAND (tmp, 1);	  break;	default:	  my_friendly_abort (77);	}      last = tmp;      tmp = TREE_OPERAND (tmp, 0);    }  last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0)));  name = build_typename_overload (last);  TREE_TYPE (name) = last;  if (of && TREE_CODE (of) == TYPE_DECL)    {      if (cname == NULL_TREE)	{	  cname = DECL_NAME (of);	  of = NULL_TREE;	}      else my_friendly_assert (cname == DECL_NAME (of), 256);    }  if (of)    {      tree this_this;      if (current_class_decl == NULL_TREE)	{	  cp_error ("object required for `operator %T' call",		    TREE_TYPE (name));	  return error_mark_node;	}      this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);      return build_component_ref (this_this, name, 0, protect);    }  else if (cname)    return build_offset_ref (cname, name);  else if (current_class_name)    return build_offset_ref (current_class_name, name);  cp_error ("object required for `operator %T' member reference",	    TREE_TYPE (name));  return error_mark_node;}#endifstatic char *thunk_printable_name (decl)     tree decl;{  return "<thunk function>";}treemake_thunk (function, delta)     tree function;     int delta;{  char buffer[250];  tree thunk_fndecl, thunk_id;  tree thunk;  char *func_name;  static int thunk_number = 0;  tree func_decl;  if (TREE_CODE (function) != ADDR_EXPR)    abort ();  func_decl = TREE_OPERAND (function, 0);  if (TREE_CODE (func_decl) != FUNCTION_DECL)    abort ();  func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func_decl));  if (delta<=0)    sprintf (buffer, "__thunk_%d_%s", -delta, func_name);  else    sprintf (buffer, "__thunk_n%d_%s", delta, func_name);  thunk_id = get_identifier (buffer);  thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);  if (thunk && TREE_CODE (thunk) != THUNK_DECL)    {      error_with_decl ("implementation-reserved name `%s' used");      IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE;    }  if (thunk == NULL_TREE)    {      thunk = build_decl (THUNK_DECL, thunk_id, TREE_TYPE (func_decl));      DECL_RESULT (thunk)	= build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (vtable_entry_type)));      TREE_READONLY (thunk) = TYPE_READONLY (TREE_TYPE (vtable_entry_type));      TREE_THIS_VOLATILE (thunk) = TYPE_VOLATILE (TREE_TYPE (vtable_entry_type));      make_function_rtl (thunk);      DECL_INITIAL (thunk) = function;      THUNK_DELTA (thunk) = delta;      /* So that finish_file can write out any thunks that need to be: */      pushdecl_top_level (thunk);    }  return thunk;}voidemit_thunk (thunk_fndecl)  tree thunk_fndecl;{  rtx insns;  char *fnname;  char buffer[250];  tree argp;  struct args_size stack_args_size;  tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0);  int delta = THUNK_DELTA (thunk_fndecl);  int tem;  int failure = 0;  int current_call_is_indirect = 0;	/* needed for HPPA FUNCTION_ARG */  /* Used to remember which regs we need to emit a USE rtx for. */  rtx need_use[FIRST_PSEUDO_REGISTER];  int need_use_count = 0;  /* rtx for the 'this' parameter. */  rtx this_rtx = 0, this_reg_rtx = 0, fixed_this_rtx;  char *(*save_decl_printable_name) () = decl_printable_name;  /* Data on reg parms scanned so far.  */  CUMULATIVE_ARGS args_so_far;  if (TREE_ASM_WRITTEN (thunk_fndecl))    return;  TREE_ASM_WRITTEN (thunk_fndecl) = 1;  if (TREE_PUBLIC (function))    {      TREE_PUBLIC (thunk_fndecl) = 1;      if (DECL_EXTERNAL (function))	{	  DECL_EXTERNAL (thunk_fndecl) = 1;	  assemble_external (thunk_fndecl);	  return;	}    }  decl_printable_name = thunk_printable_name;  if (current_function_decl)    abort ();  current_function_decl = thunk_fndecl;  init_function_start (thunk_fndecl, input_filename, lineno);  pushlevel (0);  expand_start_bindings (1);  /* Start updating where the next arg would go.  */  INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (function), NULL_RTX);  stack_args_size.constant = 0;  stack_args_size.var = 0;  /* SETUP for possible structure return address FIXME */  /* Now look through all the parameters, make sure that we     don't clobber any registers used for parameters.     Also, pick up an rtx for the first "this" parameter. */  for (argp = TYPE_ARG_TYPES (TREE_TYPE (function));       argp != NULL_TREE;       argp = TREE_CHAIN (argp))    {      tree passed_type = TREE_VALUE (argp);      register rtx entry_parm;      int named = 1; /* FIXME */      struct args_size stack_offset;      struct args_size arg_size;      if (passed_type == void_type_node)	break;      if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST	   && contains_placeholder_p (TYPE_SIZE (passed_type)))#ifdef FUNCTION_ARG_PASS_BY_REFERENCE	  || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far,					     TYPE_MODE (passed_type),					     passed_type, named)#endif	  )	passed_type = build_pointer_type (passed_type);      entry_parm = FUNCTION_ARG (args_so_far,				 TYPE_MODE (passed_type),				 passed_type,				 named);      if (entry_parm != 0)	need_use[need_use_count++] = entry_parm;      locate_and_pad_parm (TYPE_MODE (passed_type), passed_type,#ifdef STACK_PARMS_IN_REG_PARM_AREA			   1,#else			   entry_parm != 0,#endif			   thunk_fndecl,			   &stack_args_size, &stack_offset, &arg_size);/*    REGNO (entry_parm);*/      if (this_rtx == 0)	{	  this_reg_rtx = entry_parm;	  if (!entry_parm)	    {	      rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);	      rtx internal_arg_pointer, stack_parm;	      if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM		   || ! (fixed_regs[ARG_POINTER_REGNUM]			 || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))		internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);	      else		internal_arg_pointer = virtual_incoming_args_rtx;	      if (offset_rtx == const0_rtx)		entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type),				      internal_arg_pointer);	      else		entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type),				      gen_rtx (PLUS, Pmode,					       internal_arg_pointer, 					       offset_rtx));	    }	  	  this_rtx = entry_parm;	}      FUNCTION_ARG_ADVANCE (args_so_far,			    TYPE_MODE (passed_type),			    passed_type,			    named);    }  fixed_this_rtx = plus_constant (this_rtx, delta);  if (this_rtx != fixed_this_rtx)    emit_move_insn (this_rtx, fixed_this_rtx);  if (this_reg_rtx)    emit_insn (gen_rtx (USE, VOIDmode, this_reg_rtx));  emit_indirect_jump (XEXP (DECL_RTL (function), 0));  while (need_use_count > 0)    emit_insn (gen_rtx (USE, VOIDmode, need_use[--need_use_count]));  expand_end_bindings (NULL, 1, 0);  poplevel (0, 0, 1);  /* From now on, allocate rtl in current_obstack, not in saveable_obstack.     Note that that may have been done above, in save_for_inline_copying.     The call to resume_temporary_allocation near the end of this function     goes back to the usual state of affairs.  */  rtl_in_current_obstack ();  insns = get_insns ();  /* Copy any shared structure that should not be shared.  */  unshare_all_rtl (insns);  /* Instantiate all virtual registers.  */  instantiate_virtual_regs (current_function_decl, get_insns ());  /* We are no longer anticipating cse in this function, at least.  */  cse_not_expected = 1;  /* Now we choose between stupid (pcc-like) register allocation     (if we got the -noreg switch and not -opt)     and smart register allocation.  */  if (optimize > 0)			/* Stupid allocation probably won't work */    obey_regdecls = 0;		/* if optimizations being done.  */  regclass_init ();  regclass (insns, max_reg_num ());  if (obey_regdecls)    {      stupid_life_analysis (insns, max_reg_num (), NULL);      failure = reload (insns, 0, NULL);    }  else    {      /* Do control and data flow analysis,	 and write some of the results to dump file.  */      flow_analysis (insns, max_reg_num (), NULL);      local_alloc ();      failure = global_alloc (NULL);    }  reload_completed = 1;#ifdef LEAF_REGISTERS  leaf_function = 0;  if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())    leaf_function = 1;#endif  /* If a machine dependent reorganization is needed, call it.  */#ifdef MACHINE_DEPENDENT_REORG   MACHINE_DEPENDENT_REORG (insns);#endif  /* Now turn the rtl into assembler code.  */    {      char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);      assemble_start_function (thunk_fndecl, fnname);      final (insns, asm_out_file, optimize, 0);      assemble_end_function (thunk_fndecl, fnname);    }; exit_rest_of_compilation:  reload_completed = 0;  /* Cancel the effect of rtl_in_current_obstack.  */  resume_temporary_allocation ();  decl_printable_name = save_decl_printable_name;  current_function_decl = 0;}/* Code for synthesizing methods which have default semantics defined.  *//* For the anonymous union in TYPE, return the member that is at least as   large as the rest of the members, so we can copy it.  */static treelargest_union_member (type)     tree type;{  tree f, type_size = TYPE_SIZE (type);  for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f))    if (simple_cst_equal (DECL_SIZE (f), type_size) == 1)      return f;  /* We should always find one.  */  my_friendly_abort (323);  return NULL_TREE;}/* Generate code for default X(X&) constructor.  */voiddo_build_copy_constructor (fndecl)     tree fndecl;{  tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));  tree t;  clear_last_expr ();  push_momentary ();  if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))    parm = TREE_CHAIN (parm);  parm = convert_from_reference (parm);  if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))    {      t = build (INIT_EXPR, void_type_node, C_C_D, parm);      TREE_SIDE_EFFECTS (t) = 1;      cplus_expand_expr_stmt (t);    }  else    {      tree fields = TYPE_FIELDS (current_class_type);      int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);      tree binfos = TYPE_BINFO_BASETYPES (current_class_type);      int i;      for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;	   t = TREE_CHAIN (t))	{	  tree basetype = BINFO_TYPE (t);	  tree p = convert_to_reference	    (build_reference_type (basetype), parm,	     CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);	  p = convert_from_reference (p);	  current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),					      p, current_base_init_list);	}	      for (i = 0; i < n_bases; ++i)	{	  tree p, basetype = TREE_VEC_ELT (binfos, i);	  if (TREE_VIA_VIRTUAL (basetype))	    continue; 	  basetype = BINFO_TYPE (basetype);	  p = convert_to_reference	    (build_reference_type (basetype), parm,	     CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);	  p = convert_from_reference (p);	  current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),					      p, current_base_init_list);	}      for (; fields; fields = TREE_CHAIN (fields))	{	  tree name, init, t;	  tree field = fields;	  if (TREE_CODE (field) != FIELD_DECL)	    continue;	  if (DECL_NAME (field))	    {	      if (VFIELD_NAME_P (DECL_NAME (field)))		continue;	      if (VBASE_NAME_P (DECL_NAME (field)))		continue;	      /* True for duplicate members.  */	      if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)		continue;	    }	  else if ((t = TREE_TYPE (field)) != NULL_TREE		   && TREE_CODE (t) == UNION_TYPE		   && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))		   && TYPE_FIELDS (t) != NULL_TREE)	    field = largest_union_member (t);	  else	    continue;	  init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);	  init = build_tree_list (NULL_TREE, init);	  current_member_init_list	    = tree_cons (DECL_NAME (field), init, current_member_init_list);	}      current_member_init_list = nreverse (current_member_init_list);      current_base_init_list = nreverse (current_base_init_list);      setup_vtbl_ptr ();    }  pop_momentary ();}voiddo_build_assign_ref (fndecl)     tree fndecl;{  tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));  clear_last_expr ();  push_momentary ();  parm = convert_from_reference (parm);  if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type))    {      tree t = build (MODIFY_EXPR, void_type_node, C_C_D, parm);      TREE_SIDE_EFFECTS (t) = 1;      cplus_expand_expr_stmt (t);    }  else    {      tree fields = TYPE_FIELDS (current_class_type);      int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);      tree binfos = TYPE_BINFO_BASETYPES (current_class_type);      int i;      for (i = 0; i < n_bases; ++i)	{	  tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));	  if (TYPE_HAS_ASSIGN_REF (basetype))	    {	      tree p = convert_to_reference		(build_reference_type (basetype), parm,		 CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);	      p = convert_from_reference (p);	      p = build_member_call (TYPE_NESTED_NAME (basetype),				     ansi_opname [MODIFY_EXPR],				     build_tree_list (NULL_TREE, p));	      expand_expr_stmt (p);	    }	}      for (; fields; fields = TREE_CHAIN (fields))	{	  tree comp, init, t;	  tree field = fields;	  if (TREE_CODE (field) != FIELD_DECL)	    continue;	  if (DECL_NAME (field))	    {	      if (VFIELD_NAME_P (DECL_NAME (field)))		continue;	      if (VBASE_NAME_P (DECL_NAME (field)))		continue;	      /* True for duplicate members.  */	      if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)		continue;	    }	  else if ((t = TREE_TYPE (field)) != NULL_TREE		   && TREE_CODE (t) == UNION_TYPE		   && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))		   && TYPE_FIELDS (t) != NULL_TREE)	    field = largest_union_member (t);	  else	    continue;	  comp = build (COMPONENT_REF, TREE_TYPE (field), C_C_D, field);	  init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);	  expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));	}    }  c_expand_return (C_C_D);  pop_momentary ();}void push_cp_function_context ();void pop_cp_function_context ();voidsynthesize_method (fndecl)     tree fndecl;{  int nested = (current_function_decl != NULL_TREE);  tree context = decl_function_context (fndecl);  char *f = input_filename;  tree base = DECL_CLASS_CONTEXT (fndecl);  if (nested)    push_cp_function_context (context);  input_filename = DECL_SOURCE_FILE (fndecl);  interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (base);  interface_only = CLASSTYPE_INTERFACE_ONLY (base);  start_function (NULL_TREE, fndecl, NULL_TREE, NULL_TREE, 1);  store_parm_decls ();  if (DECL_NAME (fndecl) == ansi_opname[MODIFY_EXPR])    do_build_assign_ref (fndecl);  else if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))    ;  else    {      tree arg_chain = FUNCTION_ARG_CHAIN (fndecl);      if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl))	arg_chain = TREE_CHAIN (arg_chain);      if (arg_chain != void_list_node)	do_build_copy_constructor (fndecl);      else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))	setup_vtbl_ptr ();    }  finish_function (lineno, 0, nested);  /* Do we really *want* to inline this function?  */  if (DECL_INLINE (fndecl))    {      /* Turn off DECL_INLINE for the moment so function_cannot_inline_p         will check our size.  */      DECL_INLINE (fndecl) = 0;      if (function_cannot_inline_p (fndecl) == 0)	DECL_INLINE (fndecl) = 1;    }  input_filename = f;  extract_interface_info ();  if (nested)    pop_cp_function_context (context);}

⌨️ 快捷键说明

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