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

📄 convert.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Language-level data type conversion for GNU CHILL.   Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* This file contains the functions for converting CHILL expressions   to different data types.  The only entry point is `convert'.   Every language front end must have a `convert' function   but what kind of conversions it does will depend on the language.  */#include "config.h"#include "system.h"#include "tree.h"#include "ch-tree.h"#include "flags.h"#include "convert.h"#include "lex.h"#include "toplev.h"extern tree bit_one_node, bit_zero_node;extern tree string_one_type_node;extern tree bitstring_one_type_node;static treeconvert_to_reference (reftype, expr)     tree reftype, expr;{  while (TREE_CODE (expr) == NOP_EXPR)  /* RETYPE_EXPR */    expr = TREE_OPERAND (expr, 0);  if (! CH_LOCATION_P (expr))    error("internal error: trying to make loc-identity with non-location");  else    {      mark_addressable (expr);      return fold (build1 (ADDR_EXPR, reftype, expr));    }  return error_mark_node;}treeconvert_from_reference (expr)     tree expr;{  tree e = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);  TREE_READONLY (e) = TREE_READONLY (expr);  return e;}/* Convert EXPR to a boolean type.  */static treeconvert_to_boolean (type, expr)     tree type, expr;{  register tree intype = TREE_TYPE (expr);    if (integer_zerop (expr))    return boolean_false_node;  if (integer_onep (expr))    return boolean_true_node;  /* Convert a singleton bitstring to a Boolean.     Needed if flag_old_strings. */  if (CH_BOOLS_ONE_P (intype))    {      if (TREE_CODE (expr) == CONSTRUCTOR)	{	  tree valuelist = TREE_OPERAND (expr, 1);	  if (valuelist == NULL_TREE)	    return boolean_false_node;	  if (TREE_CHAIN (valuelist) == NULL_TREE	      && TREE_PURPOSE (valuelist) == NULL_TREE	      && integer_zerop (TREE_VALUE (valuelist)))	    return boolean_true_node;	}      return build_chill_bitref (expr,				 build_tree_list (NULL_TREE,						  integer_zero_node));    }  if (INTEGRAL_TYPE_P (intype))    return build1 (CONVERT_EXPR, type, expr);  error ("cannot convert to a boolean mode");  return boolean_false_node;}/* Convert EXPR to a char type.  */static treeconvert_to_char (type, expr)     tree type, expr;{  register tree intype = TREE_TYPE (expr);  register enum chill_tree_code form = TREE_CODE (intype);    if (form == CHAR_TYPE)    return build1 (NOP_EXPR, type, expr);  /* Convert a singleton string to a char.     Needed if flag_old_strings. */  if (CH_CHARS_ONE_P (intype))    {      if (TREE_CODE (expr) == STRING_CST)	{	  expr = build_int_2 ((unsigned char)TREE_STRING_POINTER(expr)[0], 0);	  TREE_TYPE (expr) = char_type_node;	  return expr;	}      else	return build (ARRAY_REF, char_type_node, expr, integer_zero_node);    }  /* For now, assume it will always fit */  if (form == INTEGER_TYPE)    return build1 (CONVERT_EXPR, type, expr);  error ("cannot convert to a char mode");  {    register tree tem = build_int_2 (0, 0);    TREE_TYPE (tem) = type;    return tem;  }}treebase_type_size_in_bytes (type)     tree type;{  if (type == NULL_TREE      || TREE_CODE (type) == ERROR_MARK      || TREE_CODE (type) != ARRAY_TYPE)    return error_mark_node;  return size_in_bytes (TREE_TYPE (type));}/* * build a singleton array type, of TYPE objects. */treebuild_array_type_for_scalar (type)     tree type;{  /* KLUDGE */  if (type == char_type_node)    return build_string_type (type, integer_one_node);  if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)    return error_mark_node;  return build_chill_array_type    (type,     tree_cons (NULL_TREE,		build_chill_range_type (NULL_TREE,					integer_zero_node, integer_zero_node),		NULL_TREE),     0, NULL_TREE);}#if 0static treeunreferenced_type_of (type)     tree type;{  if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)    return error_mark_node;  while (TREE_CODE (type) == REFERENCE_TYPE)    type = TREE_TYPE (type);  return type;}#endif/* Remove from *LISTP the first TREE_LIST node whose TREE_PURPOSE == KEY.   Return the TREE_LIST node, or NULL_TREE on failure. */static treeremove_tree_element (key, listp)     tree *listp;     tree key;{  tree node = *listp;  for ( ; node; listp = &TREE_CHAIN (node), node = *listp)    {      if (TREE_PURPOSE (node) == key)	{	  *listp = TREE_CHAIN (node);	  TREE_CHAIN (node) = NULL_TREE;	  return node;	}    }  return NULL_TREE;}/* This is quite the same as check_range in actions.c, but with   different error message. */static treecheck_ps_range (value, lo_limit, hi_limit)     tree value;     tree lo_limit;     tree hi_limit;{  tree check = test_range (value, lo_limit, hi_limit);  if (!integer_zerop (check))    {      if (TREE_CODE (check) == INTEGER_CST)	{	  error ("powerset tuple element out of range");	  return error_mark_node;	}      else	value = check_expression (value, check,				  ridpointers[(int) RID_RANGEFAIL]);    }  return value;}static treedigest_powerset_tuple (type, inits)     tree type;     tree inits;{  tree list;  tree result;  tree domain = TYPE_DOMAIN (type);  int i = 0;  int is_erroneous = 0, is_constant = 1, is_simple = 1;  if (domain == NULL_TREE || TREE_CODE (domain) == ERROR_MARK)    return error_mark_node;  for (list = TREE_OPERAND (inits, 1);  list; list = TREE_CHAIN (list), i++)    {      tree val = TREE_VALUE (list);      if (TREE_CODE (val) == ERROR_MARK)	{	  is_erroneous = 1;	  continue;	}      if (!TREE_CONSTANT (val))	is_constant = 0;      else if (!initializer_constant_valid_p (val, TREE_TYPE (val)))	is_simple = 0;      if (! CH_COMPATIBLE (val, domain))	{	  error ("incompatible member of powerset tuple (at position #%d)", i);	  is_erroneous = 1;	  continue;	}      /* check range of value */      val = check_ps_range (val, TYPE_MIN_VALUE (domain),			    TYPE_MAX_VALUE (domain));      if (TREE_CODE (val) == ERROR_MARK)	{	  is_erroneous = 1;	  continue;	}      /* Updating the list in place is in principle questionable,	 but I can't think how it could hurt. */      TREE_VALUE (list) = convert (domain, val);      val = TREE_PURPOSE (list);      if (val == NULL_TREE)	continue;      if (TREE_CODE (val) == ERROR_MARK)	{	  is_erroneous = 1;	  continue;	}      if (! CH_COMPATIBLE (val, domain))	{	  error ("incompatible member of powerset tuple (at position #%d)", i);	  is_erroneous = 1;	  continue;	}      val = check_ps_range (val, TYPE_MIN_VALUE (domain),			    TYPE_MAX_VALUE (domain));      if (TREE_CODE (val) == ERROR_MARK)	{	  is_erroneous = 1;	  continue;	}      TREE_PURPOSE (list) = convert (domain, val);      if (!TREE_CONSTANT (val))	is_constant = 0;      else if (!initializer_constant_valid_p (val, TREE_TYPE (val)))	is_simple = 0;    }  result = build (CONSTRUCTOR, type, NULL_TREE, TREE_OPERAND (inits, 1));  if (is_erroneous)    return error_mark_node;  if (is_constant)    TREE_CONSTANT (result) = 1;  if (is_constant && is_simple)    TREE_STATIC (result) = 1;  return result;}static treedigest_structure_tuple (type, inits)     tree type;     tree inits;{  tree elements = CONSTRUCTOR_ELTS (inits);  tree values = NULL_TREE;  int is_constant = 1;  int is_simple = 1;  int is_erroneous = 0;  tree field;  int labelled_elements = 0;  int unlabelled_elements = 0;  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))    {      if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE)	{ /* Regular fixed field. */	  tree value = remove_tree_element (DECL_NAME (field), &elements);	  if (value)	    labelled_elements++;	  else if (elements && TREE_PURPOSE (elements) == NULL_TREE)	    {	      value = elements;	      elements = TREE_CHAIN (elements);	      unlabelled_elements++;	    }	  if (value)	    {	      tree val;	      char msg[120];	      sprintf (msg, "initializer for field `%.80s'",		       IDENTIFIER_POINTER (DECL_NAME (field)));	      val = chill_convert_for_assignment (TREE_TYPE (field),						  TREE_VALUE (value), msg);	      if (TREE_CODE (val) == ERROR_MARK)		  is_erroneous = 1;	      else		{		  TREE_VALUE (value) = val;		  TREE_CHAIN (value) = values;		  TREE_PURPOSE (value) = field;		  values = value;			  if (TREE_CODE (val) == ERROR_MARK)		    is_erroneous = 1;		  else if (!TREE_CONSTANT (val))		    is_constant = 0;		  else if (!initializer_constant_valid_p (val,							  TREE_TYPE (val)))		    is_simple = 0;		}	    }	  else	    {	      pedwarn ("no initializer value for fixed field `%s'",		       IDENTIFIER_POINTER (DECL_NAME (field)));	    }	}      else	{	  tree variant;	  tree selected_variant = NULL_TREE;	  tree variant_values = NULL_TREE;	  /* In a tagged variant structure mode, try to figure out	     (from the fixed fields), which is the selected variant. */	  if (TYPE_TAGFIELDS (TREE_TYPE (field)))	    {	      for (variant = TYPE_FIELDS (TREE_TYPE (field));		   variant; variant = TREE_CHAIN (variant))		{		  tree tag_labels = TYPE_TAG_VALUES (TREE_TYPE (variant));		  tree tag_fields = TYPE_TAGFIELDS (TREE_TYPE (field));		  if (DECL_NAME (variant) == ELSE_VARIANT_NAME)		    {		      selected_variant = variant;		      break;		    }		  for (; tag_labels && tag_fields;		       tag_labels = TREE_CHAIN (tag_labels),		       tag_fields = TREE_CHAIN (tag_fields))		    {		      tree tag_value = values;		      int found = 0;		      tree tag_decl = TREE_VALUE (tag_fields);		      tree tag_value_set = TREE_VALUE (tag_labels);		      for ( ; tag_value; tag_value = TREE_CHAIN (tag_value))			{			  if (TREE_PURPOSE (tag_value) == tag_decl)

⌨️ 快捷键说明

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