This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: new __builtin_choose_type (patch) (new builtin_equal_typespatch)



> * C is an *integer constant expression*, not necessarily a literal
> constant.  (For example, it might be the return value of
> __builtin_types_compatible_p.)

fixed

> 
> * An implementation for C++ is also needed.

will wait for new front end like suggested.  [when's that?]

> * To use this for type-generic functions, the __builtin_choose_expr 
> goes together with __builtin_types_compatible_p which needs
> implementing as well.

done.  see patch below.

> * The actual patch submitted for inclusion in GCC should come with a
> corresponding patch to glibc's <tgmath.h> that makes it a lot simpler

uhhh, will have to work on this.  i hate tgmath.h :)

without further ado, here are the patches for  both
__builtin_choose_expr and __builtin_types_compatible_p, test cases and
docs.  i hope this one makes everone happy.

as a side note... i'm not a big fan of these big huge builtin names. 
it'll make tgmath.h horrendous to write (specially when combining
__builtin_types_compatible_p and __builtin_choose_expr in one line).

please comment...

cheers
aldy

-- 
Aldy Hernandez					E-mail: aldyh@redhat.com
Professional Gypsy on a [broken] Motorcycle
Red Hat, Inc.

2001-10-07  Aldy Hernandez  <aldyh@redhat.com>

	* testsuite/gcc.c-torture/execute/builtin-types-compatible-p.c: New.

	* testsuite/gcc.c-torture/execute/builtin-choose-expr.c: New.

	* 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): New.
	(__builtin_types_compatible_p):	New.

Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/doc/extend.texi,v
retrieving revision 1.27
diff -c -p -r1.27 extend.texi
*** extend.texi	2001/10/02 23:15:55	1.27
--- extend.texi	2001/10/08 02:28:35
*************** the same names as the standard macros ( 
*** 4342,4347 ****
--- 4342,4403 ----
  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 builtin function @code{__builtin_types_compatible_p} to
+ determine whether two types are the same.  This builtin ignores top
+ level qualifiers (e.g. const, static).  If the types are the same, this
+ builtin returns the integer constant 1.  Otherwise, 0 is returned.
+ 
+ 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
+ 
+ @end deftypefn
+ 
+ @deftypefn {Built-in Function} int __builtin_choose_expr (@var{const_exp},
+ @var{exp1}, @var{exp2})
+ 
+ You can use the builtin function @code{__builtin_choose_expr} to
+ evaluate code depending on the value of a constant expression.  This
+ builtin returns exp1 if the constant expression const_exp is non zero.
+ Otherwise it returns 0.
+ 
+ If exp1 is returned, the return type is the same as exp1's type.  The
+ expression returned has its type unaltered by promotion rules.
+ Similarly, if exp2 is returned, its return type is the same as 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),							     \
+       /* The void expression results in a compile-time error		     \
+          when assigning the result to something.  */ 			     \
+       (void)0))
+ @end smallexample
+ 
+ @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
Index: testsuite/gcc.c-torture/execute/builtin-types-compatible-p.c
===================================================================
RCS file: builtin-types-compatible-p.c
diff -N builtin-types-compatible-p.c
*** /dev/null	Tue May  5 13:32:27 1998
--- builtin-types-compatible-p.c	Sun Oct  7 19:28:35 2001
***************
*** 0 ****
--- 1,15 ----
+ int i;
+ double d;
+ 
+ main ()
+ {
+   if (__builtin_types_compatible_p (typeof (i), typeof (d)))
+     exit (1);
+   if (!__builtin_types_compatible_p (int, const int))
+     exit (1);
+   if (__builtin_types_compatible_p (char, int))
+     exit (1);
+   if (__builtin_types_compatible_p (long double, double))
+     exit (1);
+   exit (0);
+ }
Index: testsuite/gcc.c-torture/execute/builtin-choose-expr.c
===================================================================
RCS file: builtin-choose-expr.c
diff -N builtin-choose-expr.c
*** /dev/null	Tue May  5 13:32:27 1998
--- builtin-choose-expr.c	Sun Oct  7 19:28:35 2001
***************
*** 0 ****
--- 1,10 ----
+ main ()
+ {
+   if (__builtin_choose_expr (45, 0, 22))
+     exit (1);
+   if (__builtin_choose_expr (0, 12, 0))
+     exit (1);
+   if (!__builtin_choose_expr (45, 3, 0))
+     exit (1);
+   exit (0);
+ }
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.h,v
retrieving revision 1.85
diff -c -p -r1.85 c-common.h
*** c-common.h	2001/09/22 13:14:34	1.85
--- c-common.h	2001/10/08 02:28:35
*************** enum rid
*** 74,80 ****
    /* 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,
  
    /* Too many ways of getting the name of a function as a string */
    RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,
--- 74,80 ----
    /* 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_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: c-parse.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-parse.in,v
retrieving revision 1.106
diff -c -p -r1.106 c-parse.in
*** c-parse.in	2001/09/21 01:26:52	1.106
--- c-parse.in	2001/10/08 02:28:35
*************** end ifc
*** 121,127 ****
  %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 PTR_VALUE PTR_BASE PTR_EXTENT
  
  /* function name can be a string const or a var decl. */
--- 121,127 ----
  %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 CHOOSE_EXPR TYPES_COMPATIBLE_P
  %token PTR_VALUE PTR_BASE PTR_EXTENT
  
  /* function name can be a string const or a var decl. */
*************** primary:
*** 710,715 ****
--- 710,734 ----
  		{ $$ = 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));
+ 
+ 	  $$ = e1 == e2 ? build_int_2 (1, 0) : build_int_2 (0, 0);
+ 	}
  	| primary '[' expr ']'   %prec '.'
  		{ $$ = build_array_ref ($1, $3); }
  	| primary '.' identifier
*************** static const struct resword reswords[] =
*** 3290,3295 ****
--- 3309,3316 ----
    { "__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 },
*************** static const short rid_to_yy[RID_MAX] =
*** 3461,3466 ****
--- 3482,3489 ----
    /* RID_PTRBASE */	PTR_BASE,
    /* 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,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]