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

📄 gcc-func.c

📁 使用yacc和lex编写的cmm语言的词法分析和语法分析程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
tree convert (type, expr)     tree type, expr;{  register tree e = expr;  register enum tree_code code = TREE_CODE (type);  if (type == TREE_TYPE (expr) || TREE_CODE (expr) == ERROR_MARK)    return expr;  if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)    return error_mark_node;  if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)    {      error ("void value not ignored as it ought to be");      return error_mark_node;    }  if (code == VOID_TYPE)    return build1 (CONVERT_EXPR, type, e);#if 0  /* This is incorrect.  A truncation can't be stripped this way.     Extensions will be stripped by the use of get_unwidened.  */  if (TREE_CODE (expr) == NOP_EXPR)    return convert (type, TREE_OPERAND (expr, 0));#endif  if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)    return fold (convert_to_integer (type, e));  if (code == POINTER_TYPE)    return fold (convert_to_pointer (type, e));  if (code == REAL_TYPE)    return fold (convert_to_real (type, e));  error ("conversion to non-scalar type requested");  return error_mark_node;}tree default_conversion (exp)     tree exp;{  register tree type = TREE_TYPE (exp);  register enum tree_code 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 (optimize	   && TREE_CODE (exp) == VAR_DECL	   && TREE_READONLY (exp)	   && DECL_MODE (exp) != BLKmode)    {      exp = decl_constant_value (exp);      type = TREE_TYPE (exp);    }  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */  if (TREE_CODE (exp) == NON_LVALUE_EXPR)    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 (code == INTEGER_TYPE      && (TYPE_PRECISION (type)	  < TYPE_PRECISION (integer_type_node)))    {      /* Traditionally, unsignedness is preserved in default promotions.  */      if (flag_traditional && TREE_UNSIGNED (type))	return convert (unsigned_type_node, exp);      return convert (integer_type_node, exp);    }  if (flag_traditional && 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 == ARRAY_TYPE)    {      register tree adr;      tree restype = TREE_TYPE (type);      tree ptrtype;      if (TREE_CODE (exp) == INDIRECT_REF)	return convert (TYPE_POINTER_TO (restype),			TREE_OPERAND (exp, 0));      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 = c_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;}/* Make an expression to refer to the COMPONENT field of   structure or union value DATUM.  COMPONENT is an IDENTIFIER_NODE.  */treebuild_component_ref (datum, component)     tree datum, component;{  register tree type = TREE_TYPE (datum);  register enum tree_code code = TREE_CODE (type);  register tree field = NULL;  register tree ref;  /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it     unless we are not to support things not strictly ANSI.  */  switch (TREE_CODE (datum))    {    case COMPOUND_EXPR:      {	tree value = build_component_ref (TREE_OPERAND (datum, 1), component);	pedantic_lvalue_warning (COMPOUND_EXPR);	return build (COMPOUND_EXPR, TREE_TYPE (value),		      TREE_OPERAND (datum, 0), value);      }    case COND_EXPR:      pedantic_lvalue_warning (COND_EXPR);      return build_conditional_expr	(TREE_OPERAND (datum, 0),	 build_component_ref (TREE_OPERAND (datum, 1), component),	 build_component_ref (TREE_OPERAND (datum, 2), component));    }  /* See if there is a field or component with name COMPONENT.  */  if (code == RECORD_TYPE || code == UNION_TYPE)    {      if (TYPE_SIZE (type) == 0)	{	  incomplete_type_error (0, type);	  return error_mark_node;	}      /* Look up component name in the structure type definition.	 If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers	 to the field elements.  Use a binary search on this array to quickly	 find the element.  Otherwise, do a linear search.  TYPE_LANG_SPECIFIC	 will always be set for structures which have many elements.  */      if (TYPE_LANG_SPECIFIC (type))	{	  int bot, top, half;	  tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0];	  field = TYPE_FIELDS (type);	  bot = 0;	  top = TYPE_LANG_SPECIFIC (type)->len;	  while (top - bot > 1)	    {	      int cmp;	      half = (top - bot + 1) >> 1;	      field = field_array[bot+half];	      cmp = (long)DECL_NAME (field) - (long)component;	      if (cmp == 0)		break;	      if (cmp < 0)		bot += half;	      else		top = bot + half;	    }	  if (DECL_NAME (field_array[bot]) == component)	    field = field_array[bot];	  else if (DECL_NAME (field) != component)	    field = 0;	}      else	{	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))	    {	      if (DECL_NAME (field) == component)		break;	    }	}      if (!field)	{	  error (code == RECORD_TYPE		 ? "structure has no member named `%s'"		 : "union has no member named `%s'",		 IDENTIFIER_POINTER (component));	  return error_mark_node;	}      if (TREE_TYPE (field) == error_mark_node)	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;    }  else if (code != ERROR_MARK)    error ("request for member `%s' in something not a structure or union",	    IDENTIFIER_POINTER (component));  return error_mark_node;}tree build_unary_op (code, xarg, noconvert)     enum tree_code code;     tree xarg;     int noconvert;{  /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */  register tree arg = xarg;  register tree argtype = 0;  register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg));  char *errstring = NULL;  tree val;  if (typecode == ERROR_MARK)    return error_mark_node;  if (typecode == ENUMERAL_TYPE)    typecode = INTEGER_TYPE;  switch (code)    {    case CONVERT_EXPR:      /* This is used for unary plus, because a CONVERT_EXPR	 is enough to prevent anybody from looking inside for	 associativity, but won't generate any code.  */      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))        errstring = "wrong type argument to unary plus";      else if (!noconvert)	arg = default_conversion (arg);      break;

⌨️ 快捷键说明

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