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

📄 cp-typeck.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	    return p2 == void_type_node && TREE_PURPOSE (t1);	  return TREE_PURPOSE (t1) || TREE_PURPOSE (t2);#endif	}      /* Target types are compatible--just make sure that if	 we use parameter lists, that they are ok as well.  */      if (TREE_CODE (p1) == FUNCTION_TYPE || TREE_CODE (p1) == METHOD_TYPE)	switch (comp_target_parms (TYPE_ARG_TYPES (p1),				   TYPE_ARG_TYPES (p2),				   strict))	  {	  case 0:	    return 0;	  case 1:	    break;	  case 2:	    warn_contravariance = 1;	  }      if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))	{	  int cmp = simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));	  if (cmp < 0)	    my_friendly_abort (114);	  if (cmp == 0)	    return 0;	}    }  return 1 + warn_contravariance;}/* Return 1 if PARMS specifies a fixed number of parameters   and none of their types is affected by default promotions.  */static intself_promoting_args_p (parms)     tree parms;{  register tree t;  for (t = parms; t; t = TREE_CHAIN (t))    {      register tree type = TREE_VALUE (t);      if (TREE_CHAIN (t) == 0 && type != void_type_node)	return 0;      if (TYPE_MAIN_VARIANT (type) == float_type_node)	return 0;      if (type == 0)	return 0;      if (C_PROMOTING_INTEGER_TYPE_P (type))	return 0;    }  return 1;}/* Return an unsigned type the same as TYPE in other respects.   C++: must make these work for type variants as well.  */treeunsigned_type (type)     tree type;{  tree type1 = TYPE_MAIN_VARIANT (type);  if (type1 == signed_char_type_node || type1 == char_type_node)    return unsigned_char_type_node;  if (type1 == integer_type_node)    return unsigned_type_node;  if (type1 == short_integer_type_node)    return short_unsigned_type_node;  if (type1 == long_integer_type_node)    return long_unsigned_type_node;  if (type1 == long_long_integer_type_node)    return long_long_unsigned_type_node;  return type;}/* Return a signed type the same as TYPE in other respects.  */treesigned_type (type)     tree type;{  tree type1 = TYPE_MAIN_VARIANT (type);  if (type1 == unsigned_char_type_node || type1 == char_type_node)    return signed_char_type_node;  if (type1 == unsigned_type_node)    return integer_type_node;  if (type1 == short_unsigned_type_node)    return short_integer_type_node;  if (type1 == long_unsigned_type_node)    return long_integer_type_node;  if (type1 == long_long_unsigned_type_node)    return long_long_integer_type_node;  return type;}/* Return a type the same as TYPE except unsigned or   signed according to UNSIGNEDP.  */treesigned_or_unsigned_type (unsignedp, type)     int unsignedp;     tree type;{  if (TREE_CODE (type) != INTEGER_TYPE)    return type;  if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))    return unsignedp ? unsigned_char_type_node : signed_char_type_node;  if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))     return unsignedp ? unsigned_type_node : integer_type_node;  if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))     return unsignedp ? short_unsigned_type_node : short_integer_type_node;  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))     return unsignedp ? long_unsigned_type_node : long_integer_type_node;  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))     return (unsignedp ? long_long_unsigned_type_node	    : long_long_integer_type_node);  return type;}treec_sizeof (type)     tree type;{  enum tree_code code = TREE_CODE (type);  if (code == FUNCTION_TYPE)    {      if (pedantic || warn_pointer_arith)	pedwarn ("ANSI C++ forbids taking the sizeof a function type");      return size_int (1);    }  if (code == METHOD_TYPE)    {      if (pedantic || warn_pointer_arith)	pedwarn ("ANSI C++ forbids taking the sizeof a method type");      return size_int (1);    }  if (code == VOID_TYPE)    {      if (pedantic || warn_pointer_arith)	pedwarn ("ANSI C++ forbids taking the sizeof a void type");      return size_int (1);    }  if (code == ERROR_MARK)    return size_int (1);  /* C++: this is really correct!  */  if (code == REFERENCE_TYPE)    type = TREE_TYPE (type);  if (TYPE_SIZE (type) == 0)    {      error ("sizeof applied to an incomplete type");      return size_int (0);    }  /* Convert in case a char is more than one unit.  */  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 		     size_int (TYPE_PRECISION (char_type_node)));}treec_sizeof_nowarn (type)     tree type;{  enum tree_code code = TREE_CODE (type);  if (code == FUNCTION_TYPE      || code == METHOD_TYPE      || code == VOID_TYPE      || code == ERROR_MARK)    return size_int (1);  if (code == REFERENCE_TYPE)    type = TREE_TYPE (type);  if (TYPE_SIZE (type) == 0)    {      /* ??? Tiemann, why have any diagnostic here?	 There is none in the corresponding function for C.  */      warning ("sizeof applied to an incomplete type");      return size_int (0);    }  /* Convert in case a char is more than one unit.  */  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 		     size_int (TYPE_PRECISION (char_type_node)));}/* Implement the __alignof keyword: Return the minimum required   alignment of TYPE, measured in bytes.  */treec_alignof (type)     tree type;{  enum tree_code code = TREE_CODE (type);  if (code == FUNCTION_TYPE || code == METHOD_TYPE)    return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);  if (code == VOID_TYPE || code == ERROR_MARK)    return size_int (1);  /* C++: this is really correct!  */  if (code == REFERENCE_TYPE)    type = TREE_TYPE (type);  return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);}/* 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.  */treedefault_conversion (exp)     tree exp;{  register tree type = TREE_TYPE (exp);  register enum tree_code code = TREE_CODE (type);  if (code == OFFSET_TYPE)    {      if (TREE_CODE (exp) == OFFSET_REF)	return default_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) && DECL_MODE (exp) != BLKmode)    {      exp = decl_constant_value (exp);      type = TREE_TYPE (exp);    }  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.     Strip such NOP_EXPRs, since EXP is being used in non-lvalue context.  */  if (TREE_CODE (exp) == NOP_EXPR      && TREE_TYPE (exp) == TREE_TYPE (TREE_OPERAND (exp, 0)))    exp = TREE_OPERAND (exp, 0);  /* Normally convert enums to int,     but convert wide enums to something wider.  */  if (code == ENUMERAL_TYPE)    {      type = type_for_size (MAX (TYPE_PRECISION (type),				 TYPE_PRECISION (integer_type_node)),			    (flag_traditional && TREE_UNSIGNED (type)));      return convert (type, exp);    }  if (C_PROMOTING_INTEGER_TYPE_P (type))    {      /* Traditionally, unsignedness is preserved in default promotions.         Otherwise, retain unsignedness if really not getting bigger.  */      if (TREE_UNSIGNED (type)	  && (flag_traditional	      || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))	return convert (unsigned_type_node, exp);      return convert (integer_type_node, exp);    }  if (flag_traditional      && TYPE_MAIN_VARIANT (type) == float_type_node)    return convert (double_type_node, exp);  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_TYPE (type);      tree ptrtype;      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 (TYPE_POINTER_TO (TREE_TYPE (type)), inner);	}      if (TREE_CODE (exp) == COMPOUND_EXPR)	{	  tree op1 = default_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;	}      if (TYPE_READONLY (type) || TYPE_VOLATILE (type))	restype = build_type_variant (restype, TYPE_READONLY (type),				      TYPE_VOLATILE (type));      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;}/* Like `build_component_ref, but uses an already found field.   Must compute visibility 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)	error_with_decl (field, "request for member `%s' in something not a class, structure or union");      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 && ! DECL_PUBLIC (field))    {      enum visibility_type visibility	= compute_visibility (TYPE_BINFO (current_class_type), field);    if (visibility == visibility_private)      {	error_with_decl (field, "field `%s' is private");	return error_mark_node;      }    else if (visibility == visibility_protected)      {	error_with_decl (field, "field `%s' is protected");	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;  return ref;}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;

⌨️ 快捷键说明

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