public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* __builtin_choose_expr
@ 2011-10-10 15:00 Andy Gibbs
  2011-10-10 19:16 ` __builtin_choose_expr Ian Lance Taylor
  0 siblings, 1 reply; 3+ messages in thread
From: Andy Gibbs @ 2011-10-10 15:00 UTC (permalink / raw)
  To: gcc-help

Hi,

There is a very useful feature in gcc, namely __builtin_choose_expr, which 
isn't available in g++.  I expect that this is simply down to the fact that 
it had a very obvious use relating to overloading functions in C which isn't 
necessary in C++, and therefore it simply didn't get implemented.

Assuming that this was indeed the only reason, I thought rather than 
whinging that this wasn't available in C++, I'd have a go at implementing 
it.

Attached below, therefore, is a simple patch to GCC 4.6.1 which implements 
__builtin_choose_expr for C++.  From my testing, it "seems to work fine", 
but I'm afraid this is my first time hacking GCC, so I would be very 
grateful if someone much more knowledgeable than me could check over my 
patch (it should be very easy to follow) to see whether my approach is valid 
or not.

If it seems to people that this is a useful / suitable addition to GCC 
generally, then I would be happy to supplement my patch with test-cases and 
proper documentation and see whether it can be merged into the GCC trunk. 
Obviously I have uses for this feature, but I don't know whether it has a 
broader appeal!  ;o)

Thanks

Andy

--- <snip> ---

--- gcc-4.6.1-orig/gcc/c-family/c-common.c
+++ gcc-4.6.1/gcc/c-family/c-common.c
@@ -420,7 +420,7 @@ const struct c_common_resword c_common_r
   { "__asm__",  RID_ASM, 0 },
   { "__attribute", RID_ATTRIBUTE, 0 },
   { "__attribute__", RID_ATTRIBUTE, 0 },
-  { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
+  { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
   { "__builtin_offsetof", RID_OFFSETOF, 0 },
   { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
   { "__builtin_va_arg", RID_VA_ARG, 0 },
--- gcc-4.6.1-orig/gcc/cp/parser.c
+++ gcc-4.6.1/gcc/cp/parser.c
@@ -1837,6 +1837,8 @@ static tree cp_parser_expression
   (cp_parser *, bool, cp_id_kind *);
 static tree cp_parser_constant_expression
   (cp_parser *, bool, bool *);
+static tree cp_parser_builtin_choose_expr
+  (cp_parser *);
 static tree cp_parser_builtin_offsetof
   (cp_parser *);
 static tree cp_parser_lambda_expression
@@ -3850,6 +3852,9 @@ cp_parser_primary_expression (cp_parser
  case RID_OFFSETOF:
    return cp_parser_builtin_offsetof (parser);

+ case RID_CHOOSE_EXPR:
+   return cp_parser_builtin_choose_expr (parser);
+
  case RID_HAS_NOTHROW_ASSIGN:
  case RID_HAS_NOTHROW_CONSTRUCTOR:
  case RID_HAS_NOTHROW_COPY:
@@ -7403,6 +7408,43 @@ cp_parser_builtin_offsetof (cp_parser *p
   return expr;
 }

+/* Parse __builtin_choose_expr.
+
+     __builtin_choose_expr ( constant-expression ,
+        assignment-expression ,
+        assignment-expression )  */
+
+static tree
+cp_parser_builtin_choose_expr (cp_parser *parser)
+{
+  tree condition, expr_true, expr_false;
+
+  /* Consume the "__builtin_choose_expr" token.  */
+  cp_lexer_consume_token (parser->lexer);
+
+  /* Parse expressions. */
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+  condition = cp_parser_constant_expression (parser, false, NULL);
+  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+  expr_true = cp_parser_assignment_expression (parser, false, NULL);
+  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+  expr_false = cp_parser_assignment_expression (parser, false, NULL);
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
+
+  /* Fold the condition expression and convert it to a boolean value. */
+  condition = fold_non_dependent_expr (condition);
+  condition = cp_convert (boolean_type_node, condition);
+  condition = maybe_constant_value (condition);
+
+  if (TREE_CODE (condition) == INTEGER_CST)
+ return integer_zerop (condition) ? expr_false : expr_true;
+
+  error ("non-constant condition for %<__builtin_choose_expr%>");
+  cxx_constant_value (condition);
+  return error_mark_node;
+}
+
 /* Parse a trait expression.

    Returns a representation of the expression, the underlying type

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-10-11 16:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-10 15:00 __builtin_choose_expr Andy Gibbs
2011-10-10 19:16 ` __builtin_choose_expr Ian Lance Taylor
2011-10-11 16:48   ` __builtin_choose_expr Andy Gibbs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).