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

📄 typeck.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
        In that case we should be able to do better.  */  if (IS_SIGNATURE (type))    {      error ("`__alignof' applied to a signature type");      return size_int (1);    }  t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);  force_fit_type (t, 0);  return t;}/* Perform default promotions for C data used in expressions.   Arrays and functions are converted to pointers;   enumeral types or short or char, to int.   In addition, manifest constants symbols are replaced by their values.   C++: this will automatically bash references to their target type.  */treedecay_conversion (exp)     tree exp;{  register tree type = TREE_TYPE (exp);  register enum tree_code code = TREE_CODE (type);  if (code == OFFSET_TYPE /* || TREE_CODE (exp) == OFFSET_REF */ )    {      if (TREE_CODE (exp) == OFFSET_REF)	return decay_conversion (resolve_offset_ref (exp));      type = TREE_TYPE (type);      code = TREE_CODE (type);    }  if (code == REFERENCE_TYPE)    {      exp = convert_from_reference (exp);      type = TREE_TYPE (exp);      code = TREE_CODE (type);    }  /* Constants can be used directly unless they're not loadable.  */  if (TREE_CODE (exp) == CONST_DECL)    exp = DECL_INITIAL (exp);  /* Replace a nonvolatile const static variable with its value.  */  else if (TREE_READONLY_DECL_P (exp))    {      exp = decl_constant_value (exp);      type = TREE_TYPE (exp);    }  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.     Leave such NOP_EXPRs, since RHS is being used in non-lvalue context.  */  if (code == VOID_TYPE)    {      error ("void value not ignored as it ought to be");      return error_mark_node;    }  if (code == FUNCTION_TYPE)    {      return build_unary_op (ADDR_EXPR, exp, 0);    }  if (code == METHOD_TYPE)    {      if (TREE_CODE (exp) == OFFSET_REF)	{	  my_friendly_assert (TREE_CODE (TREE_OPERAND (exp, 1)) == FUNCTION_DECL,			      308);	  return build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);	}      return build_unary_op (ADDR_EXPR, exp, 0);    }  if (code == ARRAY_TYPE)    {      register tree adr;      tree restype;      tree ptrtype;      int constp, volatilep;      if (TREE_CODE (exp) == INDIRECT_REF)	{	  /* Stripping away the INDIRECT_REF is not the right	     thing to do for references...  */	  tree inner = TREE_OPERAND (exp, 0);	  if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE)	    {	      inner = build1 (CONVERT_EXPR,			      build_pointer_type (TREE_TYPE (TREE_TYPE (inner))),			      inner);	      TREE_REFERENCE_EXPR (inner) = 1;	    }	  return convert (build_pointer_type (TREE_TYPE (type)), inner);	}      if (TREE_CODE (exp) == COMPOUND_EXPR)	{	  tree op1 = decay_conversion (TREE_OPERAND (exp, 1));	  return build (COMPOUND_EXPR, TREE_TYPE (op1),			TREE_OPERAND (exp, 0), op1);	}      if (!lvalue_p (exp)	  && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))	{	  error ("invalid use of non-lvalue array");	  return error_mark_node;	}      constp = volatilep = 0;      if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r'	  || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')	{	  constp = TREE_READONLY (exp);	  volatilep = TREE_THIS_VOLATILE (exp);	}      restype = TREE_TYPE (type);      if (TYPE_READONLY (type) || TYPE_VOLATILE (type)	  || constp || volatilep)	restype = cp_build_type_variant (restype,					TYPE_READONLY (type) || constp,					TYPE_VOLATILE (type) || volatilep);      ptrtype = build_pointer_type (restype);      if (TREE_CODE (exp) == VAR_DECL)	{	  /* ??? This is not really quite correct	     in that the type of the operand of ADDR_EXPR	     is not the target type of the type of the ADDR_EXPR itself.	     Question is, can this lossage be avoided?  */	  adr = build1 (ADDR_EXPR, ptrtype, exp);	  if (mark_addressable (exp) == 0)	    return error_mark_node;	  TREE_CONSTANT (adr) = staticp (exp);	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */	  return adr;	}      /* This way is better for a COMPONENT_REF since it can	 simplify the offset for a component.  */      adr = build_unary_op (ADDR_EXPR, exp, 1);      return convert (ptrtype, adr);    }  return exp;}treedefault_conversion (exp)     tree exp;{  tree type;  enum tree_code code;  exp = decay_conversion (exp);  type = TREE_TYPE (exp);  code = TREE_CODE (type);  if (INTEGRAL_CODE_P (code))    {      tree t = type_promotes_to (type);      if (t != type)	return convert (t, exp);    }  if (flag_traditional      && TYPE_MAIN_VARIANT (type) == float_type_node)    return convert (double_type_node, exp);  return exp;}treebuild_object_ref (datum, basetype, field)     tree datum, basetype, field;{  tree dtype;  if (datum == error_mark_node)    return error_mark_node;  dtype = TREE_TYPE (datum);  if (TREE_CODE (dtype) == REFERENCE_TYPE)    dtype = TREE_TYPE (dtype);  if (! IS_AGGR_TYPE_CODE (TREE_CODE (dtype)))    {      cp_error ("request for member `%T::%D' in expression of non-aggregate type `%T'",		basetype, field, dtype);      return error_mark_node;    }  else if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (basetype)))    {      warning ("signature name in scope resolution ignored");      return build_component_ref (datum, field, NULL_TREE, 1);    }  else if (is_aggr_typedef (basetype, 1))    {      tree real_basetype = IDENTIFIER_TYPE_VALUE (basetype);      tree binfo = binfo_or_else (real_basetype, TREE_TYPE (datum));      if (binfo)	return build_component_ref (build_scoped_ref (datum, basetype),				    field, binfo, 1);    }  return error_mark_node;}/* Like `build_component_ref, but uses an already found field.   Must compute access for C_C_D.  Otherwise, ok.  */treebuild_component_ref_1 (datum, field, protect)     tree datum, field;     int protect;{  register tree basetype = TREE_TYPE (datum);  register enum tree_code code = TREE_CODE (basetype);  register tree ref;  if (code == REFERENCE_TYPE)    {      datum = convert_from_reference (datum);      basetype = TREE_TYPE (datum);      code = TREE_CODE (basetype);    }  if (! IS_AGGR_TYPE_CODE (code))    {      if (code != ERROR_MARK)	cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",		  field, datum, basetype);      return error_mark_node;    }  if (TYPE_SIZE (basetype) == 0)    {      incomplete_type_error (0, basetype);      return error_mark_node;    }  /* Look up component name in the structure type definition.  */  if (field == error_mark_node)    my_friendly_abort (115);  if (TREE_STATIC (field))    return field;  if (datum == C_C_D)    {      enum access_type access	= compute_access (TYPE_BINFO (current_class_type), field);      if (access == access_private)	{	  cp_error ("field `%D' is private", field);	  return error_mark_node;	}      else if (access == access_protected)	{	  cp_error ("field `%D' is protected", field);	  return error_mark_node;	}    }  ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field);  if (TREE_READONLY (datum) || TREE_READONLY (field))    TREE_READONLY (ref) = 1;  if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field))    TREE_THIS_VOLATILE (ref) = 1;  if (DECL_MUTABLE_P (field))    TREE_READONLY (ref) = 0;  return ref;}/* Given a COND_EXPR in T, return it in a form that we can, for   example, use as an lvalue.  This code used to be in unary_complex_lvalue,   but we needed it to deal with `a = (d == c) ? b : c' expressions, where   we're dealing with aggregates.  So, we now call this in unary_complex_lvalue,   and in build_modify_expr.  The case (in particular) that led to this was   with CODE == ADDR_EXPR, since it's not an lvalue when we'd get it there.  */static treerationalize_conditional_expr (code, t)     enum tree_code code;     tree t;{  return    build_conditional_expr (TREE_OPERAND (t, 0),			    build_unary_op (code, TREE_OPERAND (t, 1), 0),			    build_unary_op (code, TREE_OPERAND (t, 2), 0));}treebuild_component_ref (datum, component, basetype_path, protect)     tree datum, component, basetype_path;     int protect;{  register tree basetype = TREE_TYPE (datum);  register enum tree_code code = TREE_CODE (basetype);  register tree field = NULL;  register tree ref;  /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it. */  switch (TREE_CODE (datum))    {    case COMPOUND_EXPR:      {	tree value = build_component_ref (TREE_OPERAND (datum, 1), component,					  basetype_path, protect);	return build (COMPOUND_EXPR, TREE_TYPE (value),		      TREE_OPERAND (datum, 0), value);      }    case COND_EXPR:      return build_conditional_expr	(TREE_OPERAND (datum, 0),	 build_component_ref (TREE_OPERAND (datum, 1), component,			      basetype_path, protect),	 build_component_ref (TREE_OPERAND (datum, 2), component,			      basetype_path, protect));    }  if (code == REFERENCE_TYPE)    {#if 0      /* TREE_REFERENCE_EXPRs are not converted by `convert_from_reference'.	 @@ Maybe that is not right.  */      if (TREE_REFERENCE_EXPR (datum))	datum = build1 (INDIRECT_REF, TREE_TYPE (basetype), datum);      else#endif	datum = convert_from_reference (datum);      basetype = TREE_TYPE (datum);      code = TREE_CODE (basetype);    }  /* First, see if there is a field or component with name COMPONENT. */  if (TREE_CODE (component) == TREE_LIST)    {      my_friendly_assert (!(TREE_CHAIN (component) == NULL_TREE		&& DECL_CHAIN (TREE_VALUE (component)) == NULL_TREE), 309);      return build (COMPONENT_REF, TREE_TYPE (component), datum, component);    }#if 0  if (TREE_CODE (component) == TYPE_EXPR)    return build_component_type_expr (datum, component, NULL_TREE, protect);#endif  if (! IS_AGGR_TYPE_CODE (code))    {      if (code != ERROR_MARK)	cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",		  component, datum, basetype);      return error_mark_node;    }  if (TYPE_SIZE (basetype) == 0)    {      incomplete_type_error (0, basetype);      return error_mark_node;    }  if (TREE_CODE (component) == BIT_NOT_EXPR)    {      if (TYPE_IDENTIFIER (basetype) != TREE_OPERAND (component, 0))	{	  cp_error ("destructor specifier `%T::~%T' must have matching names",		    basetype, TREE_OPERAND (component, 0));	  return error_mark_node;	}      if (! TYPE_HAS_DESTRUCTOR (basetype))	{	  cp_error ("type `%T' has no destructor", basetype);	  return error_mark_node;	}      return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);    }  /* Look up component name in the structure type definition.  */  if (CLASSTYPE_VFIELD (basetype)      && DECL_NAME (CLASSTYPE_VFIELD (basetype)) == component)    /* Special-case this because if we use normal lookups in an ambiguous       hierarchy, the compiler will abort (because vptr lookups are       not supposed to be ambiguous.  */    field = CLASSTYPE_VFIELD (basetype);  else    {      if (basetype_path == NULL_TREE)	basetype_path = TYPE_BINFO (basetype);      field = lookup_field (basetype_path, component,			    protect && ! VFIELD_NAME_P (component), 0);      if (field == error_mark_node)	return error_mark_node;      if (field == NULL_TREE)	{	  /* Not found as a data field, look for it as a method.  If found,	     then if this is the only possible one, return it, else	     report ambiguity error.  */	  tree fndecls = lookup_fnfields (basetype_path, component, 1);	  if (fndecls == error_mark_node)	    return error_mark_node;	  if (fndecls)	    {	      if (TREE_CHAIN (fndecls) == NULL_TREE		  && DECL_CHAIN (TREE_VALUE (fndecls)) == NULL_TREE)		{		  enum access_type access;		  tree fndecl;		  /* Unique, so use this one now.  */		  basetype = TREE_PURPOSE (fndecls);		  fndecl = TREE_VALUE (fndecls);		  access = compute_access (TREE_PURPOSE (fndecls), fndecl);		  if (access == access_public)		    {		      if (DECL_VINDEX (fndecl)			  && ! resolves_to_fixed_type_p (datum, 0))			{			  tree addr = build_unary_op (ADDR_EXPR, datum, 0);			  addr = convert_pointer_to (DECL_CONTEXT (fndecl), addr);			  datum = build_indirect_ref (addr, NULL_PTR);			  my_friendly_assert (datum != error_mark_node, 310);			  fndecl = build_vfn_ref (&addr, datum, DECL_VINDEX (fndecl));			}		      assemble_external (fndecl);		      return fndecl;		    }		  if (access == access_protected)		    cp_error ("member function `%D' is protected", fndecl);		  else		    cp_error ("member function `%D' is private", fndecl);		  return error_mark_node;		}	      else		{		  /* Just act like build_offset_ref, since the object does                     not matter unless we're actually calling the function.  */		  tree t;		  for (t = TREE_VALUE (fndecls); t; t = DECL_CHAIN (t))		    assemble_external (t);		  t = build_tree_list (error_mark_node, fndecls);		  TREE_TYPE (t) = build_offset_type (basetype,						     unknown_type_node);		  return t;		}	    }

⌨️ 快捷键说明

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