]> granicus.if.org Git - clang/commitdiff
Template instantiation for __builtin_choose_expr.
authorDouglas Gregor <dgregor@apple.com>
Tue, 19 May 2009 22:43:30 +0000 (22:43 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 19 May 2009 22:43:30 +0000 (22:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72143 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
lib/Sema/SemaTemplateInstantiateExpr.cpp
test/SemaTemplate/instantiate-expr-3.cpp

index bb85455ddca9f26520ee41921db729fb077ae527..d2686584548bd0c5caa757ba4c41590c6eb7dc1d 100644 (file)
@@ -5043,7 +5043,7 @@ Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
   assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
 
   QualType resType;
-  if (CondExpr->isValueDependent()) {
+  if (CondExpr->isTypeDependent() || CondExpr->isValueDependent()) {
     resType = Context.DependentTy;
   } else {
     // The conditional expression is required to be a constant expression.
index ca19a3d32f17027d70cd8288af1e86f7489238bc..92a152c2e3fcf8bbd4a268630762436adc6bf82e 100644 (file)
@@ -58,6 +58,7 @@ namespace {
     OwningExprResult VisitStmtExpr(StmtExpr *E);
     OwningExprResult VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
     OwningExprResult VisitShuffleVectorExpr(ShuffleVectorExpr *E);
+    OwningExprResult VisitChooseExpr(ChooseExpr *E);
     OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
     OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
     OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
@@ -520,6 +521,25 @@ TemplateExprInstantiator::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
   return move(Result);
 }
 
+Sema::OwningExprResult 
+TemplateExprInstantiator::VisitChooseExpr(ChooseExpr *E) {
+  OwningExprResult Cond = Visit(E->getCond());
+  if (Cond.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(), TemplateArgs);
+  if (LHS.isInvalid())
+    return SemaRef.ExprError();
+
+  OwningExprResult RHS = Visit(E->getRHS());
+  if (RHS.isInvalid())
+    return SemaRef.ExprError();
+
+  return SemaRef.ActOnChooseExpr(E->getBuiltinLoc(),
+                                 move(Cond), move(LHS), move(RHS),
+                                 E->getRParenLoc());
+}
+
 Sema::OwningExprResult 
 TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
   bool isSizeOf = E->isSizeOf();
index abc2d92c6d787fe47c6257b9faac9163ec39c126..df2bdc42615fa8387e9433b37a4a52ea96a6b4f9 100644 (file)
@@ -74,6 +74,7 @@ template struct StatementExpr0<N1::X>; // expected-note{{instantiation}}
 // __builtin_shufflevector
 // ---------------------------------------------------------------------
 typedef __attribute__(( ext_vector_type(2) )) double double2;
+
 template<typename T, typename U, int N, int M>
 struct ShuffleVector0 {
   void f(T t, U u, double2 a, double2 b) {
@@ -85,3 +86,17 @@ struct ShuffleVector0 {
 
 template struct ShuffleVector0<double2, double2, 2, 1>;
 template struct ShuffleVector0<double2, double2, 4, 3>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// __builtin_choose_expr
+// ---------------------------------------------------------------------
+template<bool Cond, typename T, typename U, typename Result>
+struct Choose0 {
+  void f(T t, U u) {
+    Result r = __builtin_choose_expr(Cond, t, u); // expected-error{{lvalue}}
+  }
+};
+
+template struct Choose0<true, int, float, int&>;
+template struct Choose0<false, int, float, float&>;
+template struct Choose0<true, int, float, float&>; // expected-note{{instantiation}}