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

📄 actions.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
      if (TREE_OPERAND (label, 1) == NULL_TREE)	else_range = NULL_TREE; /* (*) -- matches everything */    }  else    else_range = update_else_range_for_range (      else_range, TREE_OPERAND (label, 0), TREE_OPERAND (label, 1));  return else_range;}static treeupdate_else_range_for_type (else_range, label)     tree else_range, label;{  tree type = TREE_TYPE (label);  else_range = update_else_range_for_range (    else_range, TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));  return else_range;}static treecompute_else_range (selector, alternatives, selector_no)     tree selector, alternatives;     int selector_no;{  /* Start with an else-range that spans the entire range of the selector type. */  tree type = TREE_TYPE (TREE_VALUE (selector));  tree range = tree_cons (TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type), NULL_TREE);  /* Now remove the values represented by each case lebel specified for that     selector. The remaining range is the else-range. */  for ( ; alternatives != NULL_TREE; alternatives = TREE_CHAIN (alternatives))    {      tree label;      tree label_list = TREE_PURPOSE (alternatives);      int  this_selector;      for (this_selector = 0; this_selector < selector_no ; ++this_selector)	label_list = TREE_CHAIN (label_list);      for (label = TREE_VALUE (label_list);	   label != NULL_TREE;	   label = TREE_CHAIN (label))	{	  tree label_value = TREE_VALUE (label);	  if (TREE_CODE (label_value) == INTEGER_CST)	    range = update_else_range_for_int_const (range, label_value);	  else if (TREE_CODE (label_value) == RANGE_EXPR)	    range = update_else_range_for_range_expr (range, label_value);	  else if (TREE_CODE (label_value) == TYPE_DECL)	    range = update_else_range_for_type (range, label_value);	  if (range == NULL_TREE)	    break;	}    }  return range;}voidcompute_else_ranges (selectors, alternatives)     tree selectors, alternatives;{  tree selector;  int selector_no = 0;  for (selector = selectors; selector != NULL_TREE; selector = TREE_CHAIN (selector))    {      if (ELSE_LABEL_SPECIFIED (selector))	TREE_PURPOSE (selector) =	  compute_else_range (selector, alternatives, selector_no);      selector_no++;    }}static treecheck_case_value (label_value, selector)     tree label_value, selector;{  if (TREE_CODE (label_value) == ERROR_MARK)    return label_value;  if (TREE_CODE (selector) == ERROR_MARK)    return selector;      /* Z.200 (6.4 Case action) says:  "The class of any discrete expression     in the case selector list must be compatible with the corresponding     (by position) class of the resulting list of classes of the case label     list occurrences ...".  We don't actually construct the resulting     list of classes, but this test should be more-or-less equivalent.     I think... */  if (!CH_COMPATIBLE_CLASSES (selector, label_value))    {      error ("case selector not compatible with label");      return error_mark_node;    }  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */  STRIP_TYPE_NOPS (label_value);  if (TREE_CODE (label_value) != INTEGER_CST)    {      error ("case label does not reduce to an integer constant");      return error_mark_node;    }  constant_expression_warning (label_value);  return label_value;}voidchill_handle_case_default (){  tree duplicate;  register tree label = build_decl (LABEL_DECL, NULL_TREE, 				    NULL_TREE);  int success = pushcase (NULL_TREE, 0, label, &duplicate);  if (success == 1)    error ("ELSE label not within a CASE statement");#if 0  else if (success == 2)    {      error ("multiple default labels found in a CASE statement");       error_with_decl (duplicate, "this is the first ELSE label");    }#endif}/* Handle cases label such as (I:J):  or (modename): */static voidchill_handle_case_label_range (min_value, max_value, selector)     tree min_value, max_value, selector;{  register tree label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);  min_value = check_case_value (min_value, selector);  max_value = check_case_value (max_value, selector);  if (TREE_CODE (min_value) != ERROR_MARK      && TREE_CODE (max_value) != ERROR_MARK)    {      tree duplicate;      int success = pushcase_range (min_value, max_value,				    convert, label, &duplicate);      if (success == 1)	error ("label found outside of CASE statement");      else if (success == 2)	{	  error ("duplicate CASE value");	  error_with_decl (duplicate, "this is the first entry for that value");	}      else if (success == 3)	error ("CASE value out of range");      else if (success == 4)	error ("empty range");      else if (success == 5)	error ("label within scope of cleanup or variable array");    }}voidchill_handle_case_label (label_value, selector)     tree label_value, selector;{  if (label_value == NULL_TREE       || TREE_CODE (label_value) == ERROR_MARK)    return;  if (TREE_CODE (label_value) == RANGE_EXPR)    {      if (TREE_OPERAND (label_value, 0) == NULL_TREE)	chill_handle_case_default ();  /* i.e. (ELSE): or (*): */      else	chill_handle_case_label_range (TREE_OPERAND (label_value, 0),				       TREE_OPERAND (label_value, 1),				       selector);    }  else if (TREE_CODE (label_value) == TYPE_DECL)    {      tree type = TREE_TYPE (label_value);      if (! discrete_type_p (type))	error ("mode in label is not discrete");      else	chill_handle_case_label_range (TYPE_MIN_VALUE (type),				       TYPE_MAX_VALUE (type),				       selector);    }  else    {      register tree label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);      label_value = check_case_value (label_value, selector);      if (TREE_CODE (label_value) != ERROR_MARK)	{	  tree duplicate;	  int success = pushcase (label_value, convert, label, &duplicate);	  if (success == 1)	    error ("label not within a CASE statement");	  else if (success == 2)	    {	      error ("duplicate case value");	      error_with_decl (duplicate, 			       "this is the first entry for that value");	    }	  else if (success == 3)	    error ("CASE value out of range");	  else if (success == 4)	    error ("empty range");	  else if (success == 5)	    error ("label within scope of cleanup or variable array");        }    }}intchill_handle_single_dimension_case_label (  selector, label_spec, expand_exit_needed, caseaction_flag)  tree selector, label_spec;  int *expand_exit_needed, *caseaction_flag;{  tree labels, one_label;  int  no_completeness_check = 0;  if (*expand_exit_needed || *caseaction_flag == 1)    {      expand_exit_something ();      *expand_exit_needed = 0;    }  for (labels = label_spec; labels != NULL_TREE; labels = TREE_CHAIN (labels))    for (one_label = TREE_VALUE (labels); one_label != NULL_TREE;         one_label = TREE_CHAIN (one_label))      {        if (TREE_VALUE (one_label) == case_else_node)          no_completeness_check = 1;        chill_handle_case_label (TREE_VALUE (one_label), selector);      }  *caseaction_flag = 1;  return no_completeness_check;}static treechill_handle_multi_case_label_range (low, high, selector)  tree low, high, selector;{  tree low_expr, high_expr, and_expr;  tree selector_type;  int  low_target_val, high_target_val;  int  low_type_val, high_type_val;  /* we can eliminate some tests is the low and/or high value in the given range     are outside the range of the selector type. */  low_target_val  = TREE_INT_CST_LOW (low);  high_target_val = TREE_INT_CST_LOW (high);  selector_type   = TREE_TYPE (selector);  low_type_val    = TREE_INT_CST_LOW (TYPE_MIN_VALUE (selector_type));  high_type_val   = TREE_INT_CST_LOW (TYPE_MAX_VALUE (selector_type));  if (low_target_val > high_type_val || high_target_val < low_type_val)    return boolean_false_node; /* selector never in range */  if (low_type_val >= low_target_val)    {      if (high_type_val <= high_target_val)	return boolean_true_node; /* always in the range */      return build_compare_expr (LE_EXPR, selector, high);    }  if (high_type_val <= high_target_val)    return build_compare_expr (GE_EXPR, selector, low);  /* The target range in completely within the range of the selector, but we     might be able to save a test if the upper bound is the same as the lower     bound. */  if (low_target_val == high_target_val)    return build_compare_expr (EQ_EXPR, selector, low);  /* No optimizations possible. Just generate tests against the upper and lower     bound of the target */  low_expr  = build_compare_expr (GE_EXPR, selector, low);  high_expr = build_compare_expr (LE_EXPR, selector, high);  and_expr  = build_chill_binary_op (TRUTH_ANDIF_EXPR, low_expr, high_expr);  return and_expr;}static treechill_handle_multi_case_else_label (selector)     tree selector;{  tree else_range, selector_value, selector_type;  tree low, high, larg;  else_range = TREE_PURPOSE (selector);  if (else_range == NULL_TREE)    return boolean_false_node; /* no values in ELSE range */  /* Test each of the ranges in the else-range chain */  selector_value = TREE_VALUE (selector);  selector_type  = TREE_TYPE (selector_value);  low  = convert (selector_type, TREE_PURPOSE (else_range));  high = convert (selector_type, TREE_VALUE (else_range));  larg = chill_handle_multi_case_label_range (low, high, selector_value);  for (else_range = TREE_CHAIN (else_range);       else_range != NULL_TREE;       else_range = TREE_CHAIN (else_range))    {      tree rarg;      low  = convert (selector_type, TREE_PURPOSE (else_range));      high = convert (selector_type, TREE_VALUE (else_range));      rarg = chill_handle_multi_case_label_range (low, high, selector_value);      larg = build_chill_binary_op (TRUTH_ORIF_EXPR, larg, rarg);    }  return larg;}static treechill_handle_multi_case_label (selector, label)  tree selector, label;{  tree expr = NULL_TREE;  if (label == NULL_TREE || TREE_CODE (label) == ERROR_MARK)    return NULL_TREE;  if (TREE_CODE (label) == INTEGER_CST)    {      int  target_val = TREE_INT_CST_LOW (label);      tree selector_type = TREE_TYPE (TREE_VALUE (selector));      int  low_type_val  = TREE_INT_CST_LOW (TYPE_MIN_VALUE (selector_type));      int  high_type_val = TREE_INT_CST_LOW (TYPE_MAX_VALUE (selector_type));      if (target_val < low_type_val || target_val > high_type_val)	expr = boolean_false_node;      else	expr = build_compare_expr (EQ_EXPR, TREE_VALUE (selector), label);    }  else if (TREE_CODE (label) == RANGE_EXPR)    {      if (TREE_OPERAND (label, 0) == NULL_TREE)	{	  if (TREE_OPERAND (label, 1) == NULL_TREE)	    expr = boolean_true_node; /* (*) -- matches everything */	  else	    expr = chill_handle_multi_case_else_label (selector);	}      else	{	  tree low = TREE_OPERAND (label, 0);	  tree high = TREE_OPERAND (label, 1);	  if (TREE_CODE (low) != INTEGER_CST)	    {	      error ("Lower bound of range must be a discrete literal expression");	      expr = error_mark_node;	    }	  if (TREE_CODE (high) != INTEGER_CST)	    {	      error ("Upper bound of range must be a discrete literal expression");	      expr = error_mark_node;	    }	  if (expr != error_mark_node)	    {	      expr = chill_handle_multi_case_label_range (                       low, high, TREE_VALUE (selector));	    }	}    }  else if (TREE_CODE (label) == TYPE_DECL)    {      tree type = TREE_TYPE (label);      if (! discrete_type_p (type))	{	  error ("mode in label is not discrete");	  expr = error_mark_node;	}      else	expr = chill_handle_multi_case_label_range (		 TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type), TREE_VALUE (selector));    }  else    {      error ("The CASE label is not valid");      expr = error_mark_node;    }  return expr;}static treechill_handle_multi_case_label_list (selector, labels)  tree selector, labels;{  tree one_label, larg, rarg;  one_label = TREE_VALUE (labels);  larg = chill_handle_multi_case_label (selector, TREE_VALUE (one_label));  for (one_label = TREE_CHAIN (one_label);       one_label != NULL_TREE;       one_label = TREE_CHAIN (one_label))    {      rarg = chill_handle_multi_case_label (selector, TREE_VALUE (one_label));      larg = build_chill_binary_op (TRUTH_ORIF_EXPR, larg, rarg);    }  return larg;}treebuild_multi_case_selector_expression (selector_list, label_spec)  tree selector_list, label_spec;{  tree labels, selector, larg, rarg;  labels   = label_spec;  selector = selector_list;  larg = chill_handle_multi_case_label_list(selector, labels);  for (labels = TREE_CHAIN (labels), selector = TREE_CHAIN (selector);       labels != NULL_TREE && selector != NULL_TREE;       labels = TREE_CHAIN (labels), selector = TREE_CHAIN (selector))    {      rarg = chill_handle_multi_case_label_list(selector, labels);      larg = build_chill_binary_op (TRUTH_ANDIF_EXPR, larg, rarg);    }  if (labels != NULL_TREE || selector != NULL_TREE)    error ("The number of CASE selectors does not match the number of CASE label lists");  return larg;}#define BITARRAY_TEST(ARRAY, INDEX) \  ((ARRAY)[(unsigned)(INDEX) / HOST_BITS_PER_CHAR]\			  & (1 << ((unsigned)(INDEX) % HOST_BITS_PER_CHAR)))#define BITARRAY_SET(ARRAY, INDEX) \  ((ARRAY)[(unsigned)(INDEX) / HOST_BITS_PER_CHAR]\			  |= 1 << ((unsigned)(INDEX) % HOST_BITS_PER_CHAR))/* CASES_SEEN is a set (bitarray) of length COUNT.   For each element that is zero, print an error message,   assume the element have the given TYPE. */static voidprint_missing_cases (type, cases_seen, count)     tree type;     unsigned char *cases_seen;     long count;

⌨️ 快捷键说明

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