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

📄 method.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
		}	      else		{		  error ("ambiguous request for method pointer `%s'",			 IDENTIFIER_POINTER (name));		  return error_mark_node;		}#endif	    }	}      if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name))	{	  return IDENTIFIER_LABEL_VALUE (name);	}      return error_mark_node;    }  type = TREE_TYPE (value);  if (TREE_CODE (value) == FIELD_DECL)    {      if (current_class_ptr == NULL_TREE)	{	  if (current_function_decl 	      && DECL_STATIC_FUNCTION_P (current_function_decl))	    cp_error ("invalid use of member `%D' in static member function",		      value);	  else	    /* We can get here when processing a bad default	       argument, like:	         struct S { int a; void f(int i = a); }  */	    cp_error ("invalid use of member `%D'", value);	  return error_mark_node;	}      TREE_USED (current_class_ptr) = 1;      /* Mark so that if we are in a constructor, and then find that	 this field was initialized by a base initializer,	 we can emit an error message.  */      TREE_USED (value) = 1;      value = build_component_ref (current_class_ref, name, NULL_TREE, 1);    }  else if ((TREE_CODE (value) == FUNCTION_DECL	    && DECL_FUNCTION_MEMBER_P (value))	   || (TREE_CODE (value) == OVERLOAD	       && DECL_FUNCTION_MEMBER_P (OVL_CURRENT (value))))    {      tree decl;      if (TREE_CODE (value) == OVERLOAD)	value = OVL_CURRENT (value);      if (IS_SIGNATURE (DECL_CLASS_CONTEXT (value)))	return value;      decl = maybe_dummy_object (DECL_CLASS_CONTEXT (value), 0);      value = build_component_ref (decl, name, NULL_TREE, 1);    }  else if (really_overloaded_fn (value))    ;  else if (TREE_CODE (value) == OVERLOAD)    /* not really overloaded function */    mark_used (OVL_FUNCTION (value));  else if (TREE_CODE (value) == TREE_LIST)    {      /* Ambiguous reference to base members, possibly other cases?.  */      tree t = value;      while (t && TREE_CODE (t) == TREE_LIST)	{	  mark_used (TREE_VALUE (t));	  t = TREE_CHAIN (t);	}    }  else if (TREE_CODE (value) == NAMESPACE_DECL)    {      cp_error ("use of namespace `%D' as expression", value);      return error_mark_node;    }  else if (DECL_CLASS_TEMPLATE_P (value))    {      cp_error ("use of class template `%T' as expression", value);      return error_mark_node;    }  else    mark_used (value);  if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL      || TREE_CODE (value) == RESULT_DECL)    {      tree context = decl_function_context (value);      if (context != NULL_TREE && context != current_function_decl	  && ! TREE_STATIC (value))	{	  cp_error ("use of %s from containing function",		      (TREE_CODE (value) == VAR_DECL		       ? "`auto' variable" : "parameter"));	  cp_error_at ("  `%#D' declared here", value);	  value = error_mark_node;	}    }  if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value))    {      if (DECL_LANG_SPECIFIC (value)	  && DECL_CLASS_CONTEXT (value) != current_class_type)	{	  tree path;	  register tree context	    = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))	      ? DECL_CLASS_CONTEXT (value)	      : DECL_CONTEXT (value);	  get_base_distance (context, current_class_type, 0, &path);	  if (path && !enforce_access (current_class_type, value))	    return error_mark_node;	}    }  else if (TREE_CODE (value) == TREE_LIST 	   && TREE_TYPE (value) == error_mark_node)    {      error ("request for member `%s' is ambiguous in multiple inheritance lattice",	     IDENTIFIER_POINTER (name));      print_candidates (value);      return error_mark_node;    }  if (! processing_template_decl)    value = convert_from_reference (value);  return value;}treemake_thunk (function, delta)     tree function;     int delta;{  tree thunk_id;  tree thunk;  tree func_decl;  if (TREE_CODE (function) != ADDR_EXPR)    abort ();  func_decl = TREE_OPERAND (function, 0);  if (TREE_CODE (func_decl) != FUNCTION_DECL)    abort ();  OB_INIT ();  OB_PUTS ("__thunk_");  if (delta > 0)    {      OB_PUTC ('n');      icat (delta);    }  else    icat (-delta);  OB_PUTC ('_');  OB_PUTID (DECL_ASSEMBLER_NAME (func_decl));  OB_FINISH ();  thunk_id = get_identifier (obstack_base (&scratch_obstack));  thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);  if (thunk && TREE_CODE (thunk) != THUNK_DECL)    {      cp_error ("implementation-reserved name `%D' used", thunk_id);      thunk = NULL_TREE;      SET_IDENTIFIER_GLOBAL_VALUE (thunk_id, thunk);    }  if (thunk == NULL_TREE)    {      thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl));      TREE_READONLY (thunk) = TREE_READONLY (func_decl);      TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (func_decl);      comdat_linkage (thunk);      TREE_SET_CODE (thunk, THUNK_DECL);      DECL_INITIAL (thunk) = function;      THUNK_DELTA (thunk) = delta;      DECL_EXTERNAL (thunk) = 1;      DECL_ARTIFICIAL (thunk) = 1;      /* So that finish_file can write out any thunks that need to be: */      pushdecl_top_level (thunk);    }  return thunk;}/* Emit the definition of a C++ multiple inheritance vtable thunk.  */voidemit_thunk (thunk_fndecl)     tree thunk_fndecl;{  tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0);  int delta = THUNK_DELTA (thunk_fndecl);  if (TREE_ASM_WRITTEN (thunk_fndecl))    return;  TREE_ASM_WRITTEN (thunk_fndecl) = 1;  TREE_ADDRESSABLE (function) = 1;  mark_used (function);  if (current_function_decl)    abort ();  TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL);  {#ifdef ASM_OUTPUT_MI_THUNK    char *fnname;    current_function_decl = thunk_fndecl;    /* Make sure we build up its RTL before we go onto the       temporary obstack.  */    make_function_rtl (thunk_fndecl);    temporary_allocation ();    DECL_RESULT (thunk_fndecl)      = build_decl (RESULT_DECL, 0, integer_type_node);    fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);    init_function_start (thunk_fndecl, input_filename, lineno);    current_function_is_thunk = 1;    assemble_start_function (thunk_fndecl, fnname);    ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function);    assemble_end_function (thunk_fndecl, fnname);    permanent_allocation (1);    current_function_decl = 0;#else /* ASM_OUTPUT_MI_THUNK */  /* If we don't have the necessary macro for efficient thunks, generate a     thunk function that just makes a call to the real function.     Unfortunately, this doesn't work for varargs.  */    tree a, t;    if (varargs_function_p (function))      cp_error ("generic thunk code fails for method `%#D' which uses `...'",		function);    /* Set up clone argument trees for the thunk.  */    t = NULL_TREE;    for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))      {	tree x = copy_node (a);	TREE_CHAIN (x) = t;	DECL_CONTEXT (x) = thunk_fndecl;	t = x;      }    a = nreverse (t);    DECL_ARGUMENTS (thunk_fndecl) = a;    DECL_RESULT (thunk_fndecl) = NULL_TREE;    DECL_LANG_SPECIFIC (thunk_fndecl) = DECL_LANG_SPECIFIC (function);    copy_lang_decl (thunk_fndecl);    DECL_INTERFACE_KNOWN (thunk_fndecl) = 1;    DECL_NOT_REALLY_EXTERN (thunk_fndecl) = 1;    start_function (NULL_TREE, thunk_fndecl, NULL_TREE, 1);    store_parm_decls ();    current_function_is_thunk = 1;    /* Build up the call to the real function.  */    t = build_int_2 (delta, -1 * (delta < 0));    TREE_TYPE (t) = signed_type (sizetype);    t = fold (build (PLUS_EXPR, TREE_TYPE (a), a, t));    t = expr_tree_cons (NULL_TREE, t, NULL_TREE);    for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))      t = expr_tree_cons (NULL_TREE, a, t);    t = nreverse (t);    t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t);    c_expand_return (t);    finish_function (lineno, 0, 0);    /* Don't let the backend defer this function.  */    if (DECL_DEFER_OUTPUT (thunk_fndecl))      {	output_inline_function (thunk_fndecl);	permanent_allocation (1);      }#endif /* ASM_OUTPUT_MI_THUNK */  }  TREE_SET_CODE (thunk_fndecl, THUNK_DECL);}voidmaybe_vlist_ctor_wrapper (fn, definep)  tree fn;  int definep;{  tree fntype, decl;  tree arg_types, parms, parm, basetype, pbasetype;  tree t, ctors;  if (!flag_vtable_thunks_compat      || !DECL_CONSTRUCTOR_FOR_PVBASE_P (fn))    return;  arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));  pbasetype = TREE_VALUE (arg_types);  basetype = TREE_TYPE (pbasetype);  parms = DECL_ARGUMENTS (fn);  /* Skip this, __in_chrg, and _vlist */  arg_types = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arg_types)));  /* Add __in_charge.  */  arg_types = hash_tree_chain (integer_type_node, arg_types);  /* Don't add this to arg_types, as build_cplus_method_type does so. */  fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)),				    arg_types);    decl = build_lang_decl (FUNCTION_DECL, DECL_NAME (fn), fntype);  DECL_LANG_SPECIFIC (decl)->decl_flags = DECL_LANG_SPECIFIC (fn)->decl_flags;  DECL_EXTERNAL (decl) = 0;  TREE_PUBLIC (decl) = 1;  DECL_ARTIFICIAL (decl) = 1;  DECL_CONSTRUCTOR_P (decl) = 1;  DECL_CONSTRUCTOR_FOR_VBASE (decl) = CONSTRUCTOR_FOR_VBASE;  /* Claim that this is never a template instantiation.  */  DECL_USE_TEMPLATE (decl) = 0;  DECL_TEMPLATE_INFO (decl) = NULL_TREE;  /* Set up clone argument trees for the thunk.  */  parms = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (parms)));  /* Add this */  t = build_decl (PARM_DECL, this_identifier, pbasetype);  SET_DECL_ARTIFICIAL (t);  DECL_ARG_TYPE (t) = pbasetype;  DECL_REGISTER (t) = 1;  /* Add __in_charge.  */  parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node);  SET_DECL_ARTIFICIAL (parm);  DECL_ARG_TYPE (parm) = integer_type_node;  TREE_CHAIN (parm) = t;  t = parm;  while (parms)    {      tree x = copy_node (parms);      TREE_CHAIN (x) = t;      DECL_CONTEXT (x) = decl;      t = x;      parms = TREE_CHAIN (parms);    }  parms = nreverse (t);  DECL_ARGUMENTS (decl) = parms;  DECL_ASSEMBLER_NAME (decl)    = build_decl_overload (DECL_NAME (decl),                           TYPE_ARG_TYPES (TREE_TYPE (decl)), 2);  ctors = CLASSTYPE_METHOD_VEC (basetype);  if (ctors)    ctors = TREE_VEC_ELT (ctors, 0);  for ( ; ctors; ctors = OVL_NEXT (ctors))    if (DECL_ASSEMBLER_NAME (OVL_CURRENT (ctors)) 	== DECL_ASSEMBLER_NAME (decl))      break;  if (!ctors)    {      add_method (basetype, 0, decl);      cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0, 0);    }  else    decl = OVL_CURRENT (ctors);  /* Remember the original function.  */  DECL_VLIST_CTOR_WRAPPED (decl) = fn;  /* If this is called from start_method, definep is -1. Then we     are inside the class, and fn is inline by default.  */  if (definep)    {      /* Record that the ctor is being defined, so we also emit the	 wrapper later. */      if (DECL_THIS_INLINE (fn)  || (definep == -1))	{	  DECL_THIS_INLINE (decl) = 1;	  DECL_INLINE (decl) = 1;	  pushdecl_top_level (decl);	}      else	{	  TREE_USED (decl) = 1;	  TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = 1;	}      mark_inline_for_output (decl);    }}static voidemit_vlist_ctor_wrapper (decl)     tree decl;{  tree t, parms, fn;  current_function_is_thunk = 1;  parms = DECL_ARGUMENTS (decl);  fn = DECL_VLIST_CTOR_WRAPPED (decl);  mark_used (fn);        /* Build up the call to the real function.  */  t = NULL_TREE;  /* Push this, __in_charge.  */  t = expr_tree_cons (NULL_TREE, parms, t);  parms = TREE_CHAIN (parms);  t = expr_tree_cons (NULL_TREE, parms, t);  parms = TREE_CHAIN (parms);  /* Push 0 as __vlist.  */  t = expr_tree_cons (NULL_TREE, vlist_zero_node, t);  /* Push rest of arguments.  */  while (parms)    {      t = expr_tree_cons (NULL_TREE, parms, t);      parms = TREE_CHAIN (parms);    }  t = nreverse (t);  t = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), t);  expand_expr_stmt (t);}/* 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.  */static 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);  if (TYPE_USES_PVBASES (current_class_type))    parm = TREE_CHAIN (parm);  parm = convert_from_reference (parm);  if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)      && is_empty_class (current_class_type))    /* Don't copy the padding byte; it might not have been allocated       if *this is a base subobject.  */;  else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))    {      t = build (INIT_EXPR, void_type_node, current_class_ref, 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;      /* Initialize all the base-classes.  */      for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;	   t = TREE_CHAIN (t))	current_base_init_list 	  = tree_cons (BINFO_TYPE (t), parm, current_base_init_list);      for (i = 0; i < n_bases; ++i)	{	  t = TREE_VEC_ELT (binfos, i);	 

⌨️ 快捷键说明

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