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

📄 init.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      dont_use_this = 1;      decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);    }  else    {      tree olddecl = current_class_ptr;      tree oldtype = TREE_TYPE (TREE_TYPE (olddecl));      if (oldtype != type)	{	  tree newtype = build_type_variant (type, TYPE_READONLY (oldtype),					     TYPE_VOLATILE (oldtype));	  decl = convert_force (build_pointer_type (newtype), olddecl, 0);	}      else	decl = olddecl;    }  decl = build_indirect_ref (decl, NULL_PTR);  if (method_name == constructor_name (type)      || method_name == constructor_name_full (type))    return build_functional_cast (type, parmlist);  if (t = lookup_fnfields (basetype_path, method_name, 0))    return build_method_call (decl, 			      TREE_CODE (name) == TEMPLATE_ID_EXPR			      ? name : method_name,			      parmlist, basetype_path,			      LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);  if (TREE_CODE (name) == IDENTIFIER_NODE      && ((t = lookup_field (TYPE_BINFO (type), name, 1, 0))))    {      if (t == error_mark_node)	return error_mark_node;      if (TREE_CODE (t) == FIELD_DECL)	{	  if (dont_use_this)	    {	      cp_error ("invalid use of non-static field `%D'", t);	      return error_mark_node;	    }	  decl = build (COMPONENT_REF, TREE_TYPE (t), decl, t);	}      else if (TREE_CODE (t) == VAR_DECL)	decl = t;      else	{	  cp_error ("invalid use of member `%D'", t);	  return error_mark_node;	}      if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl))	  && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (decl)))	return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl, parmlist, NULL_TREE);      return build_function_call (decl, parmlist);    }  else    {      cp_error ("no method `%T::%D'", type, name);      return error_mark_node;    }}/* Build a reference to a member of an aggregate.  This is not a   C++ `&', but really something which can have its address taken,   and then act as a pointer to member, for example TYPE :: FIELD   can have its address taken by saying & TYPE :: FIELD.   @@ Prints out lousy diagnostics for operator <typename>   @@ fields.   @@ This function should be rewritten and placed in search.c.  */treebuild_offset_ref (type, name)     tree type, name;{  tree decl, fnfields, fields, t = error_mark_node;  tree basebinfo = NULL_TREE;  int dtor = 0;  if (type == std_node)    return do_scoped_id (name, 0);  if (processing_template_decl)    return build_min_nt (SCOPE_REF, type, name);  /* Handle namespace names fully here.  */  if (TREE_CODE (type) == IDENTIFIER_NODE      && get_aggr_from_typedef (type, 0) == 0)    {      tree ns = lookup_name (type, 0);      tree val;      if (ns && TREE_CODE (ns) == NAMESPACE_DECL)	{	  val = lookup_namespace_name (ns, name);	  if (val)	    return val;	  cp_error ("namespace `%D' has no member named `%D'", ns, name);	  return error_mark_node;	}    }  if (type == NULL_TREE || ! is_aggr_type (type, 1))    return error_mark_node;  if (TREE_CODE (name) == BIT_NOT_EXPR)    {      dtor = 1;      name = TREE_OPERAND (name, 0);    }  if (name == constructor_name_full (type))    name = constructor_name (type);  if (TYPE_SIZE (complete_type (type)) == 0)    {      if (type == current_class_type)	t = IDENTIFIER_CLASS_VALUE (name);      else	t = NULL_TREE;      if (t == 0)	{	  cp_error ("incomplete type `%T' does not have member `%D'", type,		      name);	  return error_mark_node;	}      if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == VAR_DECL	  || TREE_CODE (t) == CONST_DECL)	{	  mark_used (t);	  return t;	}      if (TREE_CODE (t) == FIELD_DECL)	sorry ("use of member in incomplete aggregate type");      else if (TREE_CODE (t) == FUNCTION_DECL)	sorry ("use of member function in incomplete aggregate type");      else	my_friendly_abort (52);      return error_mark_node;    }  if (current_class_type == 0      || get_base_distance (type, current_class_type, 0, &basebinfo) == -1)    {      basebinfo = TYPE_BINFO (type);      decl = build1 (NOP_EXPR, type, error_mark_node);    }  else if (current_class_ptr == 0)    decl = build1 (NOP_EXPR, type, error_mark_node);  else    decl = current_class_ref;  if (constructor_name (BINFO_TYPE (basebinfo)) == name)    if (dtor)      name = dtor_identifier;    else      name = ctor_identifier;  else    if (dtor)      my_friendly_abort (999);      fnfields = lookup_fnfields (basebinfo, name, 1);  fields = lookup_field (basebinfo, name, 0, 0);  if (fields == error_mark_node || fnfields == error_mark_node)    return error_mark_node;  /* A lot of this logic is now handled in lookup_field and     lookup_fnfield.  */  if (fnfields)    {      extern int flag_save_memoized_contexts;      basebinfo = TREE_PURPOSE (fnfields);      /* Go from the TREE_BASELINK to the member function info.  */      t = TREE_VALUE (fnfields);      if (DECL_CHAIN (t) == NULL_TREE)	{	  tree access;	  /* unique functions are handled easily.  */	  access = compute_access (basebinfo, t);	  if (access == access_protected_node)	    {	      cp_error_at ("member function `%#D' is protected", t);	      error ("in this context");	      return error_mark_node;	    }	  if (access == access_private_node)	    {	      cp_error_at ("member function `%#D' is private", t);	      error ("in this context");	      return error_mark_node;	    }	  mark_used (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 (either for memoization	 or 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)	  && ((flag_save_memoized_contexts && global_bindings_p ())	      || ! allocation_temporary_p ()))	fnfields = copy_list (fnfields);      t = build_tree_list (error_mark_node, fnfields);      TREE_TYPE (t) = build_offset_type (type, unknown_type_node);      return t;    }  /* Now that we know we are looking for a field, see if we     have access to that field.  Lookup_field will give us the     error message.  */  t = lookup_field (basebinfo, name, 1, 0);  if (t == error_mark_node)    return error_mark_node;  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_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) == TREE_LIST)    return build_unary_op (ADDR_EXPR, exp, 0);  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 ((TREE_CODE (member) == VAR_DECL       && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member)))      || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE      || TREE_CODE (TREE_TYPE (member)) == METHOD_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	  || (TREE_CODE (base) == NOP_EXPR	      && TREE_OPERAND (base, 0) == error_mark_node)))    {      tree basetype_path, access;      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;	}      addr = convert_pointer_to (basetype, base);      access = compute_access (basetype_path, member);      if (access == access_public_node)	return build (COMPONENT_REF, TREE_TYPE (member),		      build_indirect_ref (addr, NULL_PTR), member);      if (access == access_protected_node)	{	  cp_error_at ("member `%D' is protected", member);	  error ("in this context");	  return error_mark_node;	}      if (access == access_private_node)	{	  cp_error_at ("member `%D' is private", member);	  error ("in this context");	  return error_mark_node;	}      my_friendly_abort (55);    }  /* Ensure that we have an object.  */  if (TREE_CODE (base) == NOP_EXPR      && TREE_OPERAND (base, 0) == error_mark_node)    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 (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE)    {      if (addr == error_mark_node)	{	  cp_error ("object missing in `%E'", exp);	  return error_mark_node;	}      basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member));      addr = convert_pointer_to (basetype, addr);      member = cp_convert (ptrdiff_type_node,			   build_unary_op (ADDR_EXPR, member, 0));            /* 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),				0);      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)#if 0      /* These may be necessary for C, but they break C++.  */      ! TREE_PUBLIC (decl)      /* Don't change a variable array bound or initial value to a constant	 in a place where a variable is invalid.  */      && ! pedantic#endif /* 0 */      && DECL_INITIAL (decl) != 0      && 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#if 0      /* We must allow this to work outside of functions so that	 static constants can be used for array sizes.  */   

⌨️ 快捷键说明

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