当前位置: 首页>>代码示例>>C++>>正文


C++ TYPE_MAIN_VARIANT函数代码示例

本文整理汇总了C++中TYPE_MAIN_VARIANT函数的典型用法代码示例。如果您正苦于以下问题:C++ TYPE_MAIN_VARIANT函数的具体用法?C++ TYPE_MAIN_VARIANT怎么用?C++ TYPE_MAIN_VARIANT使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了TYPE_MAIN_VARIANT函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: decl_attributes


//.........这里部分代码省略.........
          && is_lock_attribute_with_args (name))
        {
          TREE_PURPOSE (args) = *node;
          continue;
        }

      if (spec->decl_required && !DECL_P (*anode))
	{
	  if (flags & ((int) ATTR_FLAG_DECL_NEXT
		       | (int) ATTR_FLAG_FUNCTION_NEXT
		       | (int) ATTR_FLAG_ARRAY_NEXT))
	    {
	      /* Pass on this attribute to be tried again.  */
	      returned_attrs = tree_cons (name, args, returned_attrs);
	      continue;
	    }
	  else
	    {
	      warning (OPT_Wattributes, "%qs attribute does not apply to types",
		       IDENTIFIER_POINTER (name));
	      continue;
	    }
	}

      /* If we require a type, but were passed a decl, set up to make a
	 new type and update the one in the decl.  ATTR_FLAG_TYPE_IN_PLACE
	 would have applied if we'd been passed a type, but we cannot modify
	 the decl's type in place here.  */
      if (spec->type_required && DECL_P (*anode))
	{
	  anode = &TREE_TYPE (*anode);
	  /* Allow ATTR_FLAG_TYPE_IN_PLACE for the type's naming decl.  */
	  if (!(TREE_CODE (*anode) == TYPE_DECL
		&& *anode == TYPE_NAME (TYPE_MAIN_VARIANT
					(TREE_TYPE (*anode)))))
	    flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
	}

      if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
	  && TREE_CODE (*anode) != METHOD_TYPE)
	{
	  if (TREE_CODE (*anode) == POINTER_TYPE
	      && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
		  || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
	    {
	      /* OK, this is a bit convoluted.  We can't just make a copy
		 of the pointer type and modify its TREE_TYPE, because if
		 we change the attributes of the target type the pointer
		 type needs to have a different TYPE_MAIN_VARIANT.  So we
		 pull out the target type now, frob it as appropriate, and
		 rebuild the pointer type later.

		 This would all be simpler if attributes were part of the
		 declarator, grumble grumble.  */
	      fn_ptr_tmp = TREE_TYPE (*anode);
	      anode = &fn_ptr_tmp;
	      flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
	    }
	  else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
	    {
	      /* Pass on this attribute to be tried again.  */
	      returned_attrs = tree_cons (name, args, returned_attrs);
	      continue;
	    }

	  if (TREE_CODE (*anode) != FUNCTION_TYPE
开发者ID:IntegerCompany,项目名称:linaro-android-gcc,代码行数:67,代码来源:attribs.c

示例2: plain_type_1

static int
plain_type_1 (tree type, int level)
{
  if (type == 0)
    type = void_type_node;
  else if (type == error_mark_node)
    type = integer_type_node;
  else
    type = TYPE_MAIN_VARIANT (type);

  switch (TREE_CODE (type))
    {
    case VOID_TYPE:
    case NULLPTR_TYPE:
      return T_VOID;
    case BOOLEAN_TYPE:
    case INTEGER_TYPE:
      {
	int size = int_size_in_bytes (type) * BITS_PER_UNIT;

	/* Carefully distinguish all the standard types of C,
	   without messing up if the language is not C.
	   Note that we check only for the names that contain spaces;
	   other names might occur by coincidence in other languages.  */
	if (TYPE_NAME (type) != 0
	    && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
	    && DECL_NAME (TYPE_NAME (type)) != 0
	    && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
	  {
	    const char *const name
	      = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));

	    if (!strcmp (name, "char"))
	      return T_CHAR;
	    if (!strcmp (name, "unsigned char"))
	      return T_UCHAR;
	    if (!strcmp (name, "signed char"))
	      return T_CHAR;
	    if (!strcmp (name, "int"))
	      return T_INT;
	    if (!strcmp (name, "unsigned int"))
	      return T_UINT;
	    if (!strcmp (name, "short int"))
	      return T_SHORT;
	    if (!strcmp (name, "short unsigned int"))
	      return T_USHORT;
	    if (!strcmp (name, "long int"))
	      return T_LONG;
	    if (!strcmp (name, "long unsigned int"))
	      return T_ULONG;
	  }

	if (size == INT_TYPE_SIZE)
	  return (TYPE_UNSIGNED (type) ? T_UINT : T_INT);
	if (size == CHAR_TYPE_SIZE)
	  return (TYPE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
	if (size == SHORT_TYPE_SIZE)
	  return (TYPE_UNSIGNED (type) ? T_USHORT : T_SHORT);
	if (size == LONG_TYPE_SIZE)
	  return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
	if (size == LONG_LONG_TYPE_SIZE)	/* better than nothing */
	  return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
	return 0;
      }

    case REAL_TYPE:
      {
	int precision = TYPE_PRECISION (type);
	if (precision == FLOAT_TYPE_SIZE)
	  return T_FLOAT;
	if (precision == DOUBLE_TYPE_SIZE)
	  return T_DOUBLE;
#ifdef EXTENDED_SDB_BASIC_TYPES
	if (precision == LONG_DOUBLE_TYPE_SIZE)
	  return T_LNGDBL;
#else
	if (precision == LONG_DOUBLE_TYPE_SIZE)
	  return T_DOUBLE;	/* better than nothing */
#endif
	return 0;
      }

    case ARRAY_TYPE:
      {
	int m;
	if (level >= 6)
	  return T_VOID;
	else
	  m = plain_type_1 (TREE_TYPE (type), level+1);
	if (sdb_n_dims < SDB_MAX_DIM)
	  sdb_dims[sdb_n_dims++]
	    = (TYPE_DOMAIN (type)
	       && TYPE_MIN_VALUE (TYPE_DOMAIN (type)) != 0
	       && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != 0
	       && host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
	       && host_integerp (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0)
	       ? (tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
		  - tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) + 1)
	       : 0);

//.........这里部分代码省略.........
开发者ID:BoxianLai,项目名称:moxiedev,代码行数:101,代码来源:sdbout.c

示例3: ocp_convert


//.........这里部分代码省略.........
		     "the result of the conversion is unspecified because "
		     "%qE is outside the range of type %qT",
		     expr, type);
	}
      if (MAYBE_CLASS_TYPE_P (intype))
	{
	  tree rval;
	  rval = build_type_conversion (type, e);
	  if (rval)
	    return rval;
	  if (flags & LOOKUP_COMPLAIN)
	    error ("%q#T used where a %qT was expected", intype, type);
	  return error_mark_node;
	}
      if (code == BOOLEAN_TYPE)
	return cp_truthvalue_conversion (e);

      return fold_if_not_in_template (convert_to_integer (type, e));
    }
  if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))
    return fold_if_not_in_template (cp_convert_to_pointer (type, e));
  if (code == VECTOR_TYPE)
    {
      tree in_vtype = TREE_TYPE (e);
      if (MAYBE_CLASS_TYPE_P (in_vtype))
	{
	  tree ret_val;
	  ret_val = build_type_conversion (type, e);
	  if (ret_val)
	    return ret_val;
	  if (flags & LOOKUP_COMPLAIN)
	    error ("%q#T used where a %qT was expected", in_vtype, type);
	  return error_mark_node;
	}
      return fold_if_not_in_template (convert_to_vector (type, e));
    }
  if (code == REAL_TYPE || code == COMPLEX_TYPE)
    {
      if (MAYBE_CLASS_TYPE_P (TREE_TYPE (e)))
	{
	  tree rval;
	  rval = build_type_conversion (type, e);
	  if (rval)
	    return rval;
	  else
	    if (flags & LOOKUP_COMPLAIN)
	      error ("%q#T used where a floating point value was expected",
			TREE_TYPE (e));
	}
      if (code == REAL_TYPE)
	return fold_if_not_in_template (convert_to_real (type, e));
      else if (code == COMPLEX_TYPE)
	return fold_if_not_in_template (convert_to_complex (type, e));
    }

  /* New C++ semantics:  since assignment is now based on
     memberwise copying,  if the rhs type is derived from the
     lhs type, then we may still do a conversion.  */
  if (RECORD_OR_UNION_CODE_P (code))
    {
      tree dtype = TREE_TYPE (e);
      tree ctor = NULL_TREE;

      dtype = TYPE_MAIN_VARIANT (dtype);

      /* Conversion between aggregate types.  New C++ semantics allow
	 objects of derived type to be cast to objects of base type.
	 Old semantics only allowed this between pointers.

	 There may be some ambiguity between using a constructor
	 vs. using a type conversion operator when both apply.  */

      ctor = e;

      if (abstract_virtuals_error (NULL_TREE, type))
	return error_mark_node;

      if (BRACE_ENCLOSED_INITIALIZER_P (ctor))
	ctor = perform_implicit_conversion (type, ctor, tf_warning_or_error);
      else if ((flags & LOOKUP_ONLYCONVERTING)
	       && ! (CLASS_TYPE_P (dtype) && DERIVED_FROM_P (type, dtype)))
	/* For copy-initialization, first we create a temp of the proper type
	   with a user-defined conversion sequence, then we direct-initialize
	   the target with the temp (see [dcl.init]).  */
	ctor = build_user_type_conversion (type, ctor, flags);
      else
	ctor = build_special_member_call (NULL_TREE,
					  complete_ctor_identifier,
					  build_tree_list (NULL_TREE, ctor),
					  type, flags,
                                          tf_warning_or_error);
      if (ctor)
	return build_cplus_new (type, ctor);
    }

  if (flags & LOOKUP_COMPLAIN)
    error ("conversion from %qT to non-scalar type %qT requested",
	   TREE_TYPE (expr), type);
  return error_mark_node;
}
开发者ID:h4ck3rm1k3,项目名称:gcc,代码行数:101,代码来源:cvt.c

示例4: lambda_expr_this_capture


//.........这里部分代码省略.........
	  && TREE_CODE (LAMBDA_EXPR_EXTRA_SCOPE (lambda)) == FIELD_DECL)
	return scope_chain->x_current_class_ptr;
      return lookup_name (this_identifier);
    }

  /* Try to default capture 'this' if we can.  */
  if (!this_capture
      && (!add_capture_p
          || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE))
    {
      tree lambda_stack = NULL_TREE;
      tree init = NULL_TREE;

      /* If we are in a lambda function, we can move out until we hit:
           1. a non-lambda function or NSDMI,
           2. a lambda function capturing 'this', or
           3. a non-default capturing lambda function.  */
      for (tree tlambda = lambda; ;)
	{
          lambda_stack = tree_cons (NULL_TREE,
                                    tlambda,
                                    lambda_stack);

	  if (LAMBDA_EXPR_EXTRA_SCOPE (tlambda)
	      && TREE_CODE (LAMBDA_EXPR_EXTRA_SCOPE (tlambda)) == FIELD_DECL)
	    {
	      /* In an NSDMI, we don't have a function to look up the decl in,
		 but the fake 'this' pointer that we're using for parsing is
		 in scope_chain.  */
	      init = scope_chain->x_current_class_ptr;
	      gcc_checking_assert
		(init && (TREE_TYPE (TREE_TYPE (init))
			  == current_nonlambda_class_type ()));
	      break;
	    }

	  tree closure_decl = TYPE_NAME (LAMBDA_EXPR_CLOSURE (tlambda));
	  tree containing_function = decl_function_context (closure_decl);

	  if (containing_function == NULL_TREE)
	    /* We ran out of scopes; there's no 'this' to capture.  */
	    break;

	  if (!LAMBDA_FUNCTION_P (containing_function))
	    {
	      /* We found a non-lambda function.  */
	      if (DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function))
		/* First parameter is 'this'.  */
		init = DECL_ARGUMENTS (containing_function);
	      break;
	    }

	  tlambda
            = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function));

          if (LAMBDA_EXPR_THIS_CAPTURE (tlambda))
	    {
	      /* An outer lambda has already captured 'this'.  */
	      init = LAMBDA_EXPR_THIS_CAPTURE (tlambda);
	      break;
	    }

	  if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (tlambda) == CPLD_NONE)
	    /* An outer lambda won't let us capture 'this'.  */
	    break;
	}

      if (init)
        {
          if (add_capture_p)
	    this_capture = add_default_capture (lambda_stack,
					        /*id=*/this_identifier,
					        init);
          else
	    this_capture = init;
        }
    }

  if (!this_capture)
    {
      error ("%<this%> was not captured for this lambda function");
      result = error_mark_node;
    }
  else
    {
      /* To make sure that current_class_ref is for the lambda.  */
      gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref))
		  == LAMBDA_EXPR_CLOSURE (lambda));

      result = this_capture;

      /* If 'this' is captured, each use of 'this' is transformed into an
	 access to the corresponding unnamed data member of the closure
	 type cast (_expr.cast_ 5.4) to the type of 'this'. [ The cast
	 ensures that the transformed expression is an rvalue. ] */
      result = rvalue (result);
    }

  return result;
}
开发者ID:sylvestre,项目名称:gcc,代码行数:101,代码来源:lambda.c

示例5: build_dynamic_cast_1


//.........这里部分代码省略.........
	  tree retval;
          tree result, td2, td3, elems;
          tree static_type, target_type, boff;

 	  /* If we got here, we can't convert statically.  Therefore,
	     dynamic_cast<D&>(b) (b an object) cannot succeed.  */
	  if (tc == REFERENCE_TYPE)
	    {
	      if (TREE_CODE (old_expr) == VAR_DECL
		  && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
		{
	          tree expr = throw_bad_cast ();
		  warning ("dynamic_cast of %q#D to %q#T can never succeed",
                           old_expr, type);
	          /* Bash it to the expected type.  */
	          TREE_TYPE (expr) = type;
		  return expr;
		}
	    }
	  /* Ditto for dynamic_cast<D*>(&b).  */
	  else if (TREE_CODE (expr) == ADDR_EXPR)
	    {
	      tree op = TREE_OPERAND (expr, 0);
	      if (TREE_CODE (op) == VAR_DECL
		  && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
		{
		  warning ("dynamic_cast of %q#D to %q#T can never succeed",
                           op, type);
		  retval = build_int_cst (type, 0); 
		  return retval;
		}
	    }

	  target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
	  static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
	  td2 = get_tinfo_decl (target_type);
	  mark_used (td2);
	  td2 = build_unary_op (ADDR_EXPR, td2, 0);
	  td3 = get_tinfo_decl (static_type);
	  mark_used (td3);
	  td3 = build_unary_op (ADDR_EXPR, td3, 0);

          /* Determine how T and V are related.  */
          boff = dcast_base_hint (static_type, target_type);
          
	  /* Since expr is used twice below, save it.  */
	  expr = save_expr (expr);

	  expr1 = expr;
	  if (tc == REFERENCE_TYPE)
	    expr1 = build_unary_op (ADDR_EXPR, expr1, 0);

	  elems = tree_cons
	    (NULL_TREE, expr1, tree_cons
	     (NULL_TREE, td3, tree_cons
	      (NULL_TREE, td2, tree_cons
	       (NULL_TREE, boff, NULL_TREE))));

	  dcast_fn = dynamic_cast_node;
	  if (!dcast_fn)
	    {
	      tree tmp;
	      tree tinfo_ptr;
	      tree ns = abi_node;
	      const char *name;
	      
开发者ID:DJHartley,项目名称:iphone-dev,代码行数:66,代码来源:rtti.c

示例6: convert

tree
convert (tree type, tree expr)
{
  tree e = expr;
  enum tree_code code = TREE_CODE (type);
  const char *invalid_conv_diag;
  tree ret;
  location_t loc = EXPR_LOCATION (expr);

  if (type == error_mark_node
      || expr == error_mark_node
      || TREE_TYPE (expr) == error_mark_node)
    return error_mark_node;

  if ((invalid_conv_diag
       = targetm.invalid_conversion (TREE_TYPE (expr), type)))
    {
      error (invalid_conv_diag);
      return error_mark_node;
    }

  if (type == TREE_TYPE (expr))
    return expr;
  ret = targetm.convert_to_type (type, expr);
  if (ret)
      return ret;

  STRIP_TYPE_NOPS (e);

  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
    return fold_convert_loc (loc, type, 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;
    }

  switch (code)
    {
    case VOID_TYPE:
      return fold_convert_loc (loc, type, e);

    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
      ret = convert_to_integer (type, e);
      goto maybe_fold;

    case BOOLEAN_TYPE:
      return fold_convert_loc
	(loc, type, c_objc_common_truthvalue_conversion (input_location, expr));

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      ret = convert_to_pointer (type, e);
      goto maybe_fold;

    case REAL_TYPE:
      ret = convert_to_real (type, e);
      goto maybe_fold;

    case FIXED_POINT_TYPE:
      ret = convert_to_fixed (type, e);
      goto maybe_fold;

    case COMPLEX_TYPE:
      ret = convert_to_complex (type, e);
      goto maybe_fold;

    case VECTOR_TYPE:
      ret = convert_to_vector (type, e);
      goto maybe_fold;

    case RECORD_TYPE:
    case UNION_TYPE:
      if (lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))
	return e;
      break;

    default:
      break;

    maybe_fold:
      if (TREE_CODE (ret) != C_MAYBE_CONST_EXPR)
	ret = fold (ret);
      return ret;
    }

  error ("conversion to non-scalar type requested");
  return error_mark_node;
}
开发者ID:Bitblade,项目名称:gcc,代码行数:92,代码来源:c-convert.c

示例7: convert

tree
convert (tree type, tree expr)
{
  tree e = expr;
  enum tree_code code = TREE_CODE (type);
  const char *invalid_conv_diag;
  tree ret;
  location_t loc = EXPR_LOCATION (expr);

  if (type == error_mark_node
      || error_operand_p (expr))
    return error_mark_node;

  if ((invalid_conv_diag
       = targetm.invalid_conversion (TREE_TYPE (expr), type)))
    {
      error (invalid_conv_diag);
      return error_mark_node;
    }

  if (type == TREE_TYPE (expr))
    return expr;
  ret = targetm.convert_to_type (type, expr);
  if (ret)
      return ret;

  STRIP_TYPE_NOPS (e);

  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))
      && (TREE_CODE (TREE_TYPE (expr)) != COMPLEX_TYPE
	  || TREE_CODE (e) == COMPLEX_EXPR))
    return fold_convert_loc (loc, type, 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;
    }

  switch (code)
    {
    case VOID_TYPE:
      return fold_convert_loc (loc, type, e);

    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
      if (flag_sanitize & SANITIZE_FLOAT_CAST
	  && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
	  && COMPLETE_TYPE_P (type)
	  && do_ubsan_in_current_function ())
	{
	  tree arg;
	  if (in_late_binary_op)
	    {
	      expr = save_expr (expr);
	      arg = expr;
	    }
	  else
	    {
	      expr = c_save_expr (expr);
	      arg = c_fully_fold (expr, false, NULL);
	    }
	  tree check = ubsan_instrument_float_cast (loc, type, expr, arg);
	  expr = fold_build1 (FIX_TRUNC_EXPR, type, expr);
	  if (check == NULL)
	    return expr;
	  return fold_build2 (COMPOUND_EXPR, TREE_TYPE (expr), check, expr);
	}
      ret = convert_to_integer (type, e);
      goto maybe_fold;

    case BOOLEAN_TYPE:
      return fold_convert_loc
	(loc, type, c_objc_common_truthvalue_conversion (input_location, expr));

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      ret = convert_to_pointer (type, e);
      goto maybe_fold;

    case REAL_TYPE:
      ret = convert_to_real (type, e);
      goto maybe_fold;

    case FIXED_POINT_TYPE:
      ret = convert_to_fixed (type, e);
      goto maybe_fold;

    case COMPLEX_TYPE:
      /* If converting from COMPLEX_TYPE to a different COMPLEX_TYPE
	 and e is not COMPLEX_EXPR, convert_to_complex uses save_expr,
	 but for the C FE c_save_expr needs to be called instead.  */
      if (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE)
	{
	  if (TREE_CODE (e) != COMPLEX_EXPR)
	    {
	      tree subtype = TREE_TYPE (type);
	      tree elt_type = TREE_TYPE (TREE_TYPE (e));

//.........这里部分代码省略.........
开发者ID:shabesoglu,项目名称:gcc,代码行数:101,代码来源:c-convert.c

示例8: useless_type_conversion_p

bool
useless_type_conversion_p (tree outer_type, tree inner_type)
{
    /* Do the following before stripping toplevel qualifiers.  */
    if (POINTER_TYPE_P (inner_type)
            && POINTER_TYPE_P (outer_type))
    {
        /* Do not lose casts between pointers to different address spaces.  */
        if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type))
                != TYPE_ADDR_SPACE (TREE_TYPE (inner_type)))
            return false;
        /* Do not lose casts to function pointer types.  */
        if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
                || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
                && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE
                     || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE))
            return false;
    }

    /* From now on qualifiers on value types do not matter.  */
    inner_type = TYPE_MAIN_VARIANT (inner_type);
    outer_type = TYPE_MAIN_VARIANT (outer_type);

    if (inner_type == outer_type)
        return true;

    /* If we know the canonical types, compare them.  */
    if (TYPE_CANONICAL (inner_type)
            && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type))
        return true;

    /* Changes in machine mode are never useless conversions unless we
       deal with aggregate types in which case we defer to later checks.  */
    if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type)
            && !AGGREGATE_TYPE_P (inner_type))
        return false;

    /* If both the inner and outer types are integral types, then the
       conversion is not necessary if they have the same mode and
       signedness and precision, and both or neither are boolean.  */
    if (INTEGRAL_TYPE_P (inner_type)
            && INTEGRAL_TYPE_P (outer_type))
    {
        /* Preserve changes in signedness or precision.  */
        if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
                || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
            return false;

        /* Preserve conversions to/from BOOLEAN_TYPE if types are not
        of precision one.  */
        if (((TREE_CODE (inner_type) == BOOLEAN_TYPE)
                != (TREE_CODE (outer_type) == BOOLEAN_TYPE))
                && TYPE_PRECISION (outer_type) != 1)
            return false;

        /* We don't need to preserve changes in the types minimum or
        maximum value in general as these do not generate code
         unless the types precisions are different.  */
        return true;
    }

    /* Scalar floating point types with the same mode are compatible.  */
    else if (SCALAR_FLOAT_TYPE_P (inner_type)
             && SCALAR_FLOAT_TYPE_P (outer_type))
        return true;

    /* Fixed point types with the same mode are compatible.  */
    else if (FIXED_POINT_TYPE_P (inner_type)
             && FIXED_POINT_TYPE_P (outer_type))
        return true;

    /* We need to take special care recursing to pointed-to types.  */
    else if (POINTER_TYPE_P (inner_type)
             && POINTER_TYPE_P (outer_type))
    {
        /* We do not care for const qualification of the pointed-to types
        as const qualification has no semantic value to the middle-end.  */

        /* Otherwise pointers/references are equivalent.  */
        return true;
    }

    /* Recurse for complex types.  */
    else if (TREE_CODE (inner_type) == COMPLEX_TYPE
             && TREE_CODE (outer_type) == COMPLEX_TYPE)
        return useless_type_conversion_p (TREE_TYPE (outer_type),
                                          TREE_TYPE (inner_type));

    /* Recurse for vector types with the same number of subparts.  */
    else if (TREE_CODE (inner_type) == VECTOR_TYPE
             && TREE_CODE (outer_type) == VECTOR_TYPE
             && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
        return useless_type_conversion_p (TREE_TYPE (outer_type),
                                          TREE_TYPE (inner_type));

    else if (TREE_CODE (inner_type) == ARRAY_TYPE
             && TREE_CODE (outer_type) == ARRAY_TYPE)
    {
        /* Preserve string attributes.  */
        if (TYPE_STRING_FLAG (inner_type) != TYPE_STRING_FLAG (outer_type))
//.........这里部分代码省略.........
开发者ID:nguyentu1602,项目名称:gcc,代码行数:101,代码来源:gimple-expr.c

示例9: ocp_convert

tree
ocp_convert (tree type, tree expr, int convtype, int flags)
{
  tree e = expr;
  enum tree_code code = TREE_CODE (type);

  if (error_operand_p (e) || type == error_mark_node)
    return error_mark_node;

  complete_type (type);
  complete_type (TREE_TYPE (expr));

  e = decl_constant_value (e);

  if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP)
      /* Some internal structures (vtable_entry_type, sigtbl_ptr_type)
	 don't go through finish_struct, so they don't have the synthesized
	 constructors.  So don't force a temporary.  */
      && TYPE_HAS_CONSTRUCTOR (type))
    /* We need a new temporary; don't take this shortcut.  */;
  else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
    {
      if (same_type_p (type, TREE_TYPE (e)))
	/* The call to fold will not always remove the NOP_EXPR as
	   might be expected, since if one of the types is a typedef;
	   the comparison in fold is just equality of pointers, not a
	   call to comptypes.  We don't call fold in this case because
	   that can result in infinite recursion; fold will call
	   convert, which will call ocp_convert, etc.  */
	return e;
      /* For complex data types, we need to perform componentwise
         conversion.  */
      else if (TREE_CODE (type) == COMPLEX_TYPE)
        return fold (convert_to_complex (type, e));
      else if (TREE_CODE (e) == TARGET_EXPR)
	{
	  /* Don't build a NOP_EXPR of class type.  Instead, change the
	     type of the temporary.  Only allow this for cv-qual changes,
	     though.  */
	  if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (e)),
			    TYPE_MAIN_VARIANT (type)))
	    abort ();
	  TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
	  return e;
	}
      else if (TREE_ADDRESSABLE (type))
	/* We shouldn't be treating objects of ADDRESSABLE type as rvalues.  */
	abort ();
      else
	return fold (build1 (NOP_EXPR, type, e));
    }

  if (code == VOID_TYPE && (convtype & CONV_STATIC))
    {
      e = convert_to_void (e, /*implicit=*/NULL);
      return e;
    }

  if (INTEGRAL_CODE_P (code))
    {
      tree intype = TREE_TYPE (e);
      /* enum = enum, enum = int, enum = float, (enum)pointer are all
         errors.  */
      if (TREE_CODE (type) == ENUMERAL_TYPE
	  && ((ARITHMETIC_TYPE_P (intype) && ! (convtype & CONV_STATIC))
	      || (TREE_CODE (intype) == POINTER_TYPE)))
	{
	  pedwarn ("conversion from `%#T' to `%#T'", intype, type);

	  if (flag_pedantic_errors)
	    return error_mark_node;
	}
      if (IS_AGGR_TYPE (intype))
	{
	  tree rval;
	  rval = build_type_conversion (type, e);
	  if (rval)
	    return rval;
	  if (flags & LOOKUP_COMPLAIN)
	    error ("`%#T' used where a `%T' was expected", intype, type);
	  if (flags & LOOKUP_SPECULATIVELY)
	    return NULL_TREE;
	  return error_mark_node;
	}
      if (code == BOOLEAN_TYPE)
	return cp_truthvalue_conversion (e);

      return fold (convert_to_integer (type, e));
    }
  if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))
    return fold (cp_convert_to_pointer (type, e, false));
  if (code == VECTOR_TYPE)
    return fold (convert_to_vector (type, e));
  if (code == REAL_TYPE || code == COMPLEX_TYPE)
    {
      if (IS_AGGR_TYPE (TREE_TYPE (e)))
	{
	  tree rval;
	  rval = build_type_conversion (type, e);
	  if (rval)
//.........这里部分代码省略.........
开发者ID:Fokycnuk,项目名称:gcc,代码行数:101,代码来源:cvt.c

示例10: c_types_compatible_p

int
c_types_compatible_p (tree x, tree y)
{
  return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y));
}
开发者ID:Akheon23,项目名称:chromecast-mirrored-source.toolchain,代码行数:5,代码来源:c-objc-common.c

示例11: decl_attributes


//.........这里部分代码省略.........
	    {
	      /* Pass on this attribute to be tried again.  */
	      returned_attrs = tree_cons (name, args, returned_attrs);
	      continue;
	    }
	  else
	    {
	      warning (OPT_Wattributes, "%qE attribute does not apply to types",
		       name);
	      continue;
	    }
	}

      /* If we require a type, but were passed a decl, set up to make a
	 new type and update the one in the decl.  ATTR_FLAG_TYPE_IN_PLACE
	 would have applied if we'd been passed a type, but we cannot modify
	 the decl's type in place here.  */
      if (spec->type_required && DECL_P (*anode))
	{
	  anode = &TREE_TYPE (*anode);
	  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
	}

      if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
	  && TREE_CODE (*anode) != METHOD_TYPE)
	{
	  if (TREE_CODE (*anode) == POINTER_TYPE
	      && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
		  || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
	    {
	      /* OK, this is a bit convoluted.  We can't just make a copy
		 of the pointer type and modify its TREE_TYPE, because if
		 we change the attributes of the target type the pointer
		 type needs to have a different TYPE_MAIN_VARIANT.  So we
		 pull out the target type now, frob it as appropriate, and
		 rebuild the pointer type later.

		 This would all be simpler if attributes were part of the
		 declarator, grumble grumble.  */
	      fn_ptr_tmp = TREE_TYPE (*anode);
	      fn_ptr_quals = TYPE_QUALS (*anode);
	      anode = &fn_ptr_tmp;
	      flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
	    }
	  else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
	    {
	      /* Pass on this attribute to be tried again.  */
	      returned_attrs = tree_cons (name, args, returned_attrs);
	      continue;
	    }

	  if (TREE_CODE (*anode) != FUNCTION_TYPE
	      && TREE_CODE (*anode) != METHOD_TYPE)
	    {
	      warning (OPT_Wattributes,
		       "%qE attribute only applies to function types",
		       name);
	      continue;
	    }
	}

      if (TYPE_P (*anode)
	  && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
	  && TYPE_SIZE (*anode) != NULL_TREE)
	{
	  warning (OPT_Wattributes, "type attributes ignored after type is already defined");
开发者ID:krichter722,项目名称:gcc,代码行数:67,代码来源:attribs.c

示例12: spu_resolve_overloaded_builtin

/* target hook for resolve_overloaded_builtin(). Returns a function call
   RTX if we can resolve the overloaded builtin */
tree
spu_resolve_overloaded_builtin (tree fndecl, tree fnargs)
{
#define SCALAR_TYPE_P(t) (INTEGRAL_TYPE_P (t) \
			  || SCALAR_FLOAT_TYPE_P (t) \
			  || POINTER_TYPE_P (t))
  int new_fcode, fcode = DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
  struct spu_builtin_description *desc;
  tree match = NULL_TREE;

  /* The vector types are not available if the backend is not initialized.  */
  gcc_assert (!flag_preprocess_only);

  desc = &spu_builtins[fcode];
  if (desc->type != B_OVERLOAD)
    return NULL_TREE;

  /* Compare the signature of each internal builtin function with the
     function arguments until a match is found. */

  for (new_fcode = fcode + 1; spu_builtins[new_fcode].type == B_INTERNAL;
       new_fcode++)
    {
      tree decl = spu_builtins[new_fcode].fndecl;
      tree params = TYPE_ARG_TYPES (TREE_TYPE (decl));
      tree arg, param;
      bool all_scalar;
      int p;

      /* Check whether all parameters are scalar.  */
      all_scalar = true;
      for (param = params; param != void_list_node; param = TREE_CHAIN (param))
	if (!SCALAR_TYPE_P (TREE_VALUE (param)))
	  all_scalar = false;

      for (param = params, arg = fnargs, p = 0;
	   param != void_list_node;
	   param = TREE_CHAIN (param), arg = TREE_CHAIN (arg), p++)
	{
	  tree var, arg_type, param_type = TREE_VALUE (param);

	  if (!arg)
	    {
	      error ("insufficient arguments to overloaded function %s",
		     desc->name);
	      return error_mark_node;
	    }

	  var = TREE_VALUE (arg);

	  if (TREE_CODE (var) == NON_LVALUE_EXPR)
	    var = TREE_OPERAND (var, 0);

	  if (TREE_CODE (var) == ERROR_MARK)
	    return NULL_TREE;	/* Let somebody else deal with the problem. */

	  arg_type = TREE_TYPE (var);

	  /* The intrinsics spec does not specify precisely how to
	     resolve generic intrinsics.  We require an exact match
	     for vector types and let C do it's usual parameter type
	     checking/promotions for scalar arguments, except for the
	     first argument of intrinsics which don't have a vector
	     parameter. */
	  if ((!SCALAR_TYPE_P (param_type)
	       || !SCALAR_TYPE_P (arg_type)
	       || (all_scalar && p == 0))
	      && !comptypes (TYPE_MAIN_VARIANT (param_type),
			     TYPE_MAIN_VARIANT (arg_type)))
	    break;
	}
      if (param == void_list_node)
	{
	  if (arg)
	    {
	      error ("too many arguments to overloaded function %s",
		     desc->name);
	      return error_mark_node;
	    }

	  match = decl;
	  break;
	}
    }

  if (match == NULL_TREE)
    {
      error ("parameter list does not match a valid signature for %s()",
	     desc->name);
      return error_mark_node;
    }

  return build_function_call (match, fnargs);
#undef SCALAR_TYPE_P
}
开发者ID:IntegerCompany,项目名称:linaro-android-gcc,代码行数:97,代码来源:spu-c.c

示例13: s390_fn_types_compatible

/* Check whether the arguments in ARGLIST match the function type
   DEF_TYPE. Return the number of argument types which required
   conversion/promotion in order to make it match.
   0 stands for a perfect match - all operand types match without changes
   INT_MAX stands for a mismatch.  */
static int
s390_fn_types_compatible (enum s390_builtin_ov_type_index typeindex,
			  vec<tree, va_gc> *arglist)
{
  unsigned int i;
  int match_type = 0;

  for (i = 0; i < vec_safe_length (arglist); i++)
    {
      tree b_arg_type = s390_builtin_types[s390_builtin_ov_types[typeindex][i + 1]];
      tree in_arg = (*arglist)[i];
      tree in_type = TREE_TYPE (in_arg);

      if (TREE_CODE (b_arg_type) == VECTOR_TYPE)
	{
	  /* Vector types have to match precisely.  */
	  if (b_arg_type != in_type
	      && TYPE_MAIN_VARIANT (b_arg_type) != TYPE_MAIN_VARIANT (in_type))
	    goto mismatch;
	}

      if (lang_hooks.types_compatible_p (in_type, b_arg_type))
	continue;

      if (lang_hooks.types_compatible_p (
	    lang_hooks.types.type_promotes_to (in_type),
	    lang_hooks.types.type_promotes_to (b_arg_type)))
	{
	  match_type++;
	  continue;
	}

      /* In this stage the C++ frontend would go ahead trying to find
	 implicit conversion chains for the argument to match the
	 target type.  We will mimic this here only for our limited
	 subset of argument types.  */
      if (TREE_CODE (b_arg_type) == INTEGER_TYPE
	  && TREE_CODE (in_type) == INTEGER_TYPE)
	{
	  match_type++;
	  continue;
	}

      /* If the incoming pointer argument has more qualifiers than the
	 argument type it can still be an imperfect match.  */
      if (POINTER_TYPE_P (b_arg_type) && POINTER_TYPE_P (in_type)
	  && !(TYPE_QUALS (TREE_TYPE (in_type))
	       & ~TYPE_QUALS (TREE_TYPE (b_arg_type)))
	  && (TYPE_QUALS (TREE_TYPE (b_arg_type))
	      & ~TYPE_QUALS (TREE_TYPE (in_type))))
	{
	  tree qual_in_type =
	    build_qualified_type (TREE_TYPE (in_type),
				  TYPE_QUALS (TREE_TYPE (b_arg_type)));

	  if (lang_hooks.types_compatible_p (qual_in_type,
					     TREE_TYPE (b_arg_type)))
	    {
	      match_type++;
	      continue;
	    }
	}

    mismatch:
      if (TARGET_DEBUG_ARG)
	fprintf (stderr, " mismatch in operand: %d\n", i + 1);
      return INT_MAX;
    }

  return match_type;
}
开发者ID:Lucretia,项目名称:gcc,代码行数:76,代码来源:s390-c.c

示例14: cp_convert_to_pointer

static tree
cp_convert_to_pointer (tree type, tree expr, bool force)
{
  tree intype = TREE_TYPE (expr);
  enum tree_code form;
  tree rval;
  if (intype == error_mark_node)
    return error_mark_node;

  if (IS_AGGR_TYPE (intype))
    {
      intype = complete_type (intype);
      if (!COMPLETE_TYPE_P (intype))
	{
	  error ("can't convert from incomplete type `%T' to `%T'",
		    intype, type);
	  return error_mark_node;
	}

      rval = build_type_conversion (type, expr);
      if (rval)
	{
	  if (rval == error_mark_node)
	    error ("conversion of `%E' from `%T' to `%T' is ambiguous",
		      expr, intype, type);
	  return rval;
	}
    }

  /* Handle anachronistic conversions from (::*)() to cv void* or (*)().  */
  if (TREE_CODE (type) == POINTER_TYPE
      && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
	  || VOID_TYPE_P (TREE_TYPE (type))))
    {
      /* Allow an implicit this pointer for pointer to member
	 functions.  */
      if (TYPE_PTRMEMFUNC_P (intype))
	{
	  if (pedantic || warn_pmf2ptr)
	    pedwarn ("converting from `%T' to `%T'", intype, type);
	  if (TREE_CODE (expr) == PTRMEM_CST)
	    expr = build_address (PTRMEM_CST_MEMBER (expr));
	  else
	    {
	      tree decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 
					      0);
	      decl = build_address (decl);
	      expr = get_member_function_from_ptrfunc (&decl, expr);
	    }
	}
      else if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
	{
	  if (pedantic || warn_pmf2ptr)
	    pedwarn ("converting from `%T' to `%T'", intype, type);
	  expr = build_addr_func (expr);
	}
      if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
	return build_nop (type, expr);
      intype = TREE_TYPE (expr);
    }

  if (expr == error_mark_node)
    return error_mark_node;

  form = TREE_CODE (intype);

  if (POINTER_TYPE_P (intype))
    {
      intype = TYPE_MAIN_VARIANT (intype);

      if (TYPE_MAIN_VARIANT (type) != intype
	  && TREE_CODE (type) == POINTER_TYPE
	  && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
	  && IS_AGGR_TYPE (TREE_TYPE (type))
	  && IS_AGGR_TYPE (TREE_TYPE (intype))
	  && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
	{
	  enum tree_code code = PLUS_EXPR;
	  tree binfo;
	  tree intype_class;
	  tree type_class;
	  bool same_p;

	  intype_class = TREE_TYPE (intype);
	  type_class = TREE_TYPE (type);

	  same_p = same_type_p (TYPE_MAIN_VARIANT (intype_class), 
				TYPE_MAIN_VARIANT (type_class));
	  binfo = NULL_TREE;
	  /* Try derived to base conversion.  */
	  if (!same_p)
	    binfo = lookup_base (intype_class, type_class, ba_check, NULL);
	  if (!same_p && !binfo)
	    {
	      /* Try base to derived conversion.  */
	      binfo = lookup_base (type_class, intype_class, ba_check, NULL);
	      code = MINUS_EXPR;
	    }
	  if (binfo == error_mark_node)
	    return error_mark_node;
//.........这里部分代码省略.........
开发者ID:Fokycnuk,项目名称:gcc,代码行数:101,代码来源:cvt.c

示例15: decl_attributes

tree
decl_attributes (tree *node, tree attributes, int flags)
{
  tree a;
  tree returned_attrs = NULL_TREE;

  if (!attributes_initialized)
    init_attributes ();

  targetm.insert_attributes (*node, &attributes);

  for (a = attributes; a; a = TREE_CHAIN (a))
    {
      tree name = TREE_PURPOSE (a);
      tree args = TREE_VALUE (a);
      tree *anode = node;
      const struct attribute_spec *spec = NULL;
      bool no_add_attrs = 0;
      tree fn_ptr_tmp = NULL_TREE;
      size_t i;

      for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
	{
	  int j;

	  for (j = 0; attribute_tables[i][j].name != NULL; j++)
	    {
	      if (is_attribute_p (attribute_tables[i][j].name, name))
		{
		  spec = &attribute_tables[i][j];
		  break;
		}
	    }
	  if (spec != NULL)
	    break;
	}

      if (spec == NULL)
	{
	  warning ("%qs attribute directive ignored",
		   IDENTIFIER_POINTER (name));
	  continue;
	}
      else if (list_length (args) < spec->min_length
	       || (spec->max_length >= 0
		   && list_length (args) > spec->max_length))
	{
	  error ("wrong number of arguments specified for %qs attribute",
		 IDENTIFIER_POINTER (name));
	  continue;
	}

      if (spec->decl_required && !DECL_P (*anode))
	{
	  if (flags & ((int) ATTR_FLAG_DECL_NEXT
		       | (int) ATTR_FLAG_FUNCTION_NEXT
		       | (int) ATTR_FLAG_ARRAY_NEXT))
	    {
	      /* Pass on this attribute to be tried again.  */
	      returned_attrs = tree_cons (name, args, returned_attrs);
	      continue;
	    }
	  else
	    {
	      warning ("%qs attribute does not apply to types",
		       IDENTIFIER_POINTER (name));
	      continue;
	    }
	}

      /* If we require a type, but were passed a decl, set up to make a
	 new type and update the one in the decl.  ATTR_FLAG_TYPE_IN_PLACE
	 would have applied if we'd been passed a type, but we cannot modify
	 the decl's type in place here.  */
      if (spec->type_required && DECL_P (*anode))
	{
	  anode = &TREE_TYPE (*anode);
	  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
	}

      if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
	  && TREE_CODE (*anode) != METHOD_TYPE)
	{
	  if (TREE_CODE (*anode) == POINTER_TYPE
	      && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
		  || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
	    {
	      /* OK, this is a bit convoluted.  We can't just make a copy
		 of the pointer type and modify its TREE_TYPE, because if
		 we change the attributes of the target type the pointer
		 type needs to have a different TYPE_MAIN_VARIANT.  So we
		 pull out the target type now, frob it as appropriate, and
		 rebuild the pointer type later.

	         This would all be simpler if attributes were part of the
	         declarator, grumble grumble.  */
	      fn_ptr_tmp = TREE_TYPE (*anode);
	      anode = &fn_ptr_tmp;
	      flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
	    }
//.........这里部分代码省略.........
开发者ID:aosm,项目名称:gcc_40,代码行数:101,代码来源:attribs.c


注:本文中的TYPE_MAIN_VARIANT函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。