c-common.h (rid): Add RID_CHOOSE_EXPR and RID_TYPES_COMPATIBLE_P.

* c-common.h (rid): Add RID_CHOOSE_EXPR and
        RID_TYPES_COMPATIBLE_P.

        * c-parse.in (reswords): Add __builtin_choose_expr.
        Add __builtin_types_compatible_p.
        Add CHOOSE_EXPR token.
	Add TYPES_COMPATIBLE_P token.
        Add production for CHOOSE_EXPR.
        Add production for TYPES_COMPATIBLE_P.

        * doc/extend.texi (__builtin_choose_expr): Add documentation.
        (__builtin_types_compatible_p): Likewise.

From-SVN: r47798
This commit is contained in:
Aldy Hernandez 2001-12-08 22:34:54 +00:00 committed by Aldy Hernandez
parent 1ec9bf8aa0
commit ecbcf7b319
4 changed files with 132 additions and 2 deletions

View File

@ -1,3 +1,18 @@
2001-10-08 Aldy Hernandez <aldyh@redhat.com>
* c-common.h (rid): Add RID_CHOOSE_EXPR and
RID_TYPES_COMPATIBLE_P.
* c-parse.in (reswords): Add __builtin_choose_expr.
Add __builtin_types_compatible_p.
Add CHOOSE_EXPR token.
Add TYPES_COMPATIBLE_P token.
Add production for CHOOSE_EXPR.
Add production for TYPES_COMPATIBLE_P.
* doc/extend.texi (__builtin_choose_expr): Add documentation.
(__builtin_types_compatible_p): Likewise.
2001-12-08 David Edelsohn <edelsohn@gnu.org>
* stor-layout.c (place_union_field): Apply ADJUST_FIELD_ALIGN

View File

@ -74,7 +74,7 @@ enum rid
/* C extensions */
RID_ASM, RID_TYPEOF, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG,
RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_PTRBASE,
RID_PTREXTENT, RID_PTRVALUE,
RID_PTREXTENT, RID_PTRVALUE, RID_CHOOSE_EXPR, RID_TYPES_COMPATIBLE_P,
/* Too many ways of getting the name of a function as a string */
RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,

View File

@ -110,7 +110,7 @@ end ifobjc
%token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF
%token ATTRIBUTE EXTENSION LABEL
%token REALPART IMAGPART VA_ARG
%token REALPART IMAGPART VA_ARG CHOOSE_EXPR TYPES_COMPATIBLE_P
%token PTR_VALUE PTR_BASE PTR_EXTENT
/* function name can be a string const or a var decl. */
@ -664,6 +664,26 @@ primary:
{ $$ = build_function_call ($1, $3); }
| VA_ARG '(' expr_no_commas ',' typename ')'
{ $$ = build_va_arg ($3, groktypename ($5)); }
| CHOOSE_EXPR '(' expr_no_commas ',' expr_no_commas ',' expr_no_commas ')'
{
tree c;
c = fold ($3);
STRIP_NOPS (c);
if (TREE_CODE (c) != INTEGER_CST)
error ("first argument to __builtin_choose_expr not a constant");
$$ = integer_zerop (c) ? $7 : $5;
}
| TYPES_COMPATIBLE_P '(' typename ',' typename ')'
{
tree e1, e2;
e1 = TYPE_MAIN_VARIANT (groktypename ($3));
e2 = TYPE_MAIN_VARIANT (groktypename ($5));
$$ = comptypes (e1, e2)
? build_int_2 (1, 0) : build_int_2 (0, 0);
}
| primary '[' expr ']' %prec '.'
{ $$ = build_array_ref ($1, $3); }
| primary '.' identifier
@ -3218,6 +3238,8 @@ static const struct resword reswords[] =
{ "__attribute__", RID_ATTRIBUTE, 0 },
{ "__bounded", RID_BOUNDED, 0 },
{ "__bounded__", RID_BOUNDED, 0 },
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
{ "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 },
{ "__builtin_va_arg", RID_VA_ARG, 0 },
{ "__complex", RID_COMPLEX, 0 },
{ "__complex__", RID_COMPLEX, 0 },
@ -3390,6 +3412,9 @@ static const short rid_to_yy[RID_MAX] =
/* RID_PTREXTENT */ PTR_EXTENT,
/* RID_PTRVALUE */ PTR_VALUE,
/* RID_CHOOSE_EXPR */ CHOOSE_EXPR,
/* RID_TYPES_COMPATIBLE_P */ TYPES_COMPATIBLE_P,
/* RID_FUNCTION_NAME */ STRING_FUNC_NAME,
/* RID_PRETTY_FUNCTION_NAME */ STRING_FUNC_NAME,
/* RID_C99_FUNCTION_NAME */ VAR_FUNC_NAME,

View File

@ -4388,6 +4388,96 @@ the same names as the standard macros ( @code{isgreater},
prefixed. We intend for a library implementor to be able to simply
@code{#define} each standard macro to its built-in equivalent.
@deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1}, @var{type2})
You can use the built-in function @code{__builtin_types_compatible_p} to
determine whether two types are the same.
This built-in function returns 1 if the unqualified versions of the
types @var{type1} and @var{type2} (which are types, not expressions) are
compatible, 0 otherwise. The result of this built-in function can be
used in integer constant expressions.
This built-in function ignores top level qualifiers (e.g., @code{const},
@code{volatile}). For example, @code{int} is equivalent to @code{const
int}.
The type @code{int[]} and @code{int[5]} are compatible. On the other
hand, @code{int} and @code{char *} are not compatible, even if the size
of their types, on the particular architecture are the same. Also, the
amount of pointer indirection is taken into account when determining
similarity. Consequently, @code{short *} is not similar to
@code{short **}. Furthermore, two types that are typedefed are
considered compatible if their underlying types are compatible.
An @code{enum} type is considered to be compatible with another
@code{enum} type. For example, @code{enum @{foo, bar@}} is similar to
@code{enum @{hot, dog@}}.
You would typically use this function in code whose execution varies
depending on the arguments' types. For example:
@smallexample
#define foo(x) \
(@{ \
typeof (x) tmp; \
if (__builtin_types_compatible_p (typeof (x), long double)) \
tmp = foo_long_double (tmp); \
else if (__builtin_types_compatible_p (typeof (x), double)) \
tmp = foo_double (tmp); \
else if (__builtin_types_compatible_p (typeof (x), float)) \
tmp = foo_float (tmp); \
else \
abort (); \
tmp; \
@})
@end smallexample
@emph{Note:} This construct is only available for C.
@end deftypefn
@deftypefn {Built-in Function} @var{type} __builtin_choose_expr (@var{const_exp}, @var{exp1}, @var{exp2})
You can use the built-in function @code{__builtin_choose_expr} to
evaluate code depending on the value of a constant expression. This
built-in function returns @var{exp1} if @var{const_exp}, which is a
constant expression that must be able to be determined at compile time,
is nonzero. Otherwise it returns 0.
This built-in function is analogous to the @samp{? :} operator in C,
except that the expression returned has its type unaltered by promotion
rules. Also, the built-in function does not evaluate the expression
that was not chosen. For example, if @var{const_exp} evaluates to true,
@var{exp2} is not evaluated even if it has side-effects.
This built-in function can return an lvalue if the chosen argument is an
lvalue.
If @var{exp1} is returned, the return type is the same as @var{exp1}'s
type. Similarly, if @var{exp2} is returned, its return type is the same
as @var{exp2}.
Example:
@smallexample
#define foo(x) \
__builtin_choose_expr (__builtin_types_compatible_p (typeof (x), double), \
foo_double (x), \
__builtin_choose_expr (__builtin_types_compatible_p (typeof (x), float), \
foo_float (x), \
/* @r{The void expression results in a compile-time error} \
@r{when assigning the result to something.} */ \
(void)0))
@end smallexample
@emph{Note:} This construct is only available for C. Furthermore, the
unused expression (@var{exp1} or @var{exp2} depending on the value of
@var{const_exp}) may still generate syntax errors. This may change in
future revisions.
@end deftypefn
@deftypefn {Built-in Function} int __builtin_constant_p (@var{exp})
You can use the built-in function @code{__builtin_constant_p} to
determine if a value is known to be constant at compile-time and hence