c-common.h (rid): Add RID_CHOOSE_EXPR and RID_TYPES_COMPATIBLE_P.
authorAldy Hernandez <aldyh@redhat.com>
Sat, 8 Dec 2001 22:34:54 +0000 (22:34 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Sat, 8 Dec 2001 22:34:54 +0000 (22:34 +0000)
* 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

gcc/ChangeLog
gcc/c-common.h
gcc/c-parse.in
gcc/doc/extend.texi

index 799f445cfc682f2555ab2cb2141a9270f11583a2..5155954714b1bbbbf34cadcfd82495016e45ce12 100644 (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
index 33835f653db4723af95c7f48010a5d01e4d34c20..59525d5dc535fac83eac5d432494bac872603782 100644 (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,
index 324300d00e88ce15732083ae33494319ca454d14..84d1c0214b33e4e60c4b93dc141d88bf217f2d43 100644 (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,
index 5e8001088034b34f58e39d3597ee98e3ab3c5e49..1a4ff5814dfa3d88b5ef41534a17172ba3331d7c 100644 (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