tree
build_array_notation_ref (location_t loc, tree array, tree start, tree length, 
			  tree stride, tree type)
{
  tree array_ntn_expr = NULL_TREE;

  /* If we enter the then-case of the if-statement below, we have hit a case 
     like this: ARRAY [:].  */
  if (!start && !length)
    {
      if (TREE_CODE (type) != ARRAY_TYPE)
	{
	  error_at (loc, "start-index and length fields necessary for "
		    "using array notation in pointers or records");
	  return error_mark_node;
	}
      tree domain = TYPE_DOMAIN (type);
      if (!domain)
	{
	  error_at (loc, "start-index and length fields necessary for "
		    "using array notation with array of unknown bound");
	  return error_mark_node;
	}
      start = cp_fold_convert (ptrdiff_type_node, TYPE_MINVAL (domain));
      length = size_binop (PLUS_EXPR, TYPE_MAXVAL (domain), size_one_node);
      length = cp_fold_convert (ptrdiff_type_node, length);
    }
    
  if (!stride) 
    stride = build_one_cst (ptrdiff_type_node);
  
  /* When dealing with templates, triplet type-checking will be done in pt.c 
     after type substitution.  */
  if (processing_template_decl 
      && (type_dependent_expression_p (array) 
	  || type_dependent_expression_p (length) 
	  || type_dependent_expression_p (start) 
	  || type_dependent_expression_p (stride))) 
    array_ntn_expr = build_min_nt_loc (loc, ARRAY_NOTATION_REF, array, start, 
				       length, stride, NULL_TREE);
  else 
    { 
      if (!cilkplus_an_triplet_types_ok_p (loc, start, length, stride, type))
	return error_mark_node;
      array_ntn_expr = build4 (ARRAY_NOTATION_REF, NULL_TREE, array, start, 
			       length, stride);
    }
  if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == POINTER_TYPE)
    TREE_TYPE (array_ntn_expr) = TREE_TYPE (type);
  else
    gcc_unreachable ();

  SET_EXPR_LOCATION (array_ntn_expr, loc);
  return array_ntn_expr;
}
Beispiel #2
0
tree
build_must_not_throw_expr (tree body, tree cond)
{
  tree type = body ? TREE_TYPE (body) : void_type_node;

  if (!flag_exceptions)
    return body;

  if (!cond)
    /* OK, unconditional.  */;
  else
    {
      tree conv = NULL_TREE;
      if (!type_dependent_expression_p (cond))
	conv = perform_implicit_conversion_flags (boolean_type_node, cond,
						  tf_warning_or_error,
						  LOOKUP_NORMAL);
      if (tree inst = instantiate_non_dependent_or_null (conv))
	cond = cxx_constant_value (inst);
      else
	require_constant_expression (cond);
      if (integer_zerop (cond))
	return body;
      else if (integer_onep (cond))
	cond = NULL_TREE;
    }

  return build2 (MUST_NOT_THROW_EXPR, type, body, cond);
}
Beispiel #3
0
tree
lambda_return_type (tree expr)
{
  if (expr == NULL_TREE)
    return void_type_node;
  if (type_unknown_p (expr)
      || BRACE_ENCLOSED_INITIALIZER_P (expr))
    {
      cxx_incomplete_type_error (expr, TREE_TYPE (expr));
      return void_type_node;
    }
  gcc_checking_assert (!type_dependent_expression_p (expr));
  return cv_unqualified (type_decays_to (unlowered_expr_type (expr)));
}
Beispiel #4
0
tree
lambda_capture_field_type (tree expr, bool explicit_init_p)
{
  tree type;
  if (explicit_init_p)
    {
      type = make_auto ();
      type = do_auto_deduction (type, expr, type);
    }
  else
    type = non_reference (unlowered_expr_type (expr));
  if (type_dependent_expression_p (expr)
      && !is_this_parameter (tree_strip_nop_conversions (expr)))
    {
      type = cxx_make_type (DECLTYPE_TYPE);
      DECLTYPE_TYPE_EXPR (type) = expr;
      DECLTYPE_FOR_LAMBDA_CAPTURE (type) = true;
      DECLTYPE_FOR_INIT_CAPTURE (type) = explicit_init_p;
      SET_TYPE_STRUCTURAL_EQUALITY (type);
    }
  return type;
}