Implement __builtin_choose_expr.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40794 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/Sema.h b/Sema/Sema.h
index ff2e5d1..b6d4797 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -285,6 +285,11 @@
   virtual ExprResult ParseTypesCompatibleExpr(SourceLocation BuiltinLoc, 
                                               TypeTy *arg1, TypeTy *arg2,
                                               SourceLocation RPLoc);
+                                              
+  // __builtin_choose_expr(constExpr, expr1, expr2)
+  virtual ExprResult ParseChooseExpr(SourceLocation BuiltinLoc, 
+                                     ExprTy *cond, ExprTy *expr1, ExprTy *expr2,
+                                     SourceLocation RPLoc);
   
   /// ParseCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
   virtual ExprResult ParseCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index 2f072f1..7a42006 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -1584,3 +1584,25 @@
   return new TypesCompatibleExpr(Context.IntTy, BuiltinLoc, argT1, argT2, RPLoc);
 }
 
+Sema::ExprResult Sema::ParseChooseExpr(SourceLocation BuiltinLoc, ExprTy *cond, 
+                                       ExprTy *expr1, ExprTy *expr2,
+                                       SourceLocation RPLoc) {
+  Expr *CondExpr = static_cast<Expr*>(cond);
+  Expr *LHSExpr = static_cast<Expr*>(expr1);
+  Expr *RHSExpr = static_cast<Expr*>(expr2);
+  
+  assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
+
+  // The conditional expression is required to be a constant expression.
+  llvm::APSInt condEval(32);
+  SourceLocation ExpLoc;
+  if (!CondExpr->isIntegerConstantExpr(condEval, Context, &ExpLoc))
+    return Diag(ExpLoc, diag::err_typecheck_choose_expr_requires_constant,
+                 CondExpr->getSourceRange());
+
+  // If the condition is > zero, then the AST type is the same as the LSHExpr.
+  QualType resType = condEval.getZExtValue() ? LHSExpr->getType() : 
+                                               RHSExpr->getType();
+  return new ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, RPLoc);
+}
+