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:
parent
1ec9bf8aa0
commit
ecbcf7b319
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user