aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2001-12-08 22:34:54 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2001-12-08 22:34:54 +0000
commitecbcf7b3198489daee27a8dd913314a69e947c11 (patch)
treebb7979ef02dfccc51f11263c3f2803727502419e /gcc
parent1ec9bf8aa0d0b2375e43668f4a6c186856c9dbc9 (diff)
downloadgcc-ecbcf7b3198489daee27a8dd913314a69e947c11.zip
gcc-ecbcf7b3198489daee27a8dd913314a69e947c11.tar.gz
gcc-ecbcf7b3198489daee27a8dd913314a69e947c11.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/c-common.h2
-rw-r--r--gcc/c-parse.in27
-rw-r--r--gcc/doc/extend.texi90
4 files changed, 132 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 799f445..5155954 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 33835f6..59525d5 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -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,
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index 324300d..84d1c02 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -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,
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 5e80010..1a4ff58 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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