From: Douglas Gregor Date: Tue, 19 May 2009 22:43:30 +0000 (+0000) Subject: Template instantiation for __builtin_choose_expr. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c9ecc57d6d1fd4a96c748e52958d70be3b3da9fb;p=clang Template instantiation for __builtin_choose_expr. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72143 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index bb85455ddc..d268658454 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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. diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp index ca19a3d32f..92a152c2e3 100644 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -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(); diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp index abc2d92c6d..df2bdc4261 100644 --- a/test/SemaTemplate/instantiate-expr-3.cpp +++ b/test/SemaTemplate/instantiate-expr-3.cpp @@ -74,6 +74,7 @@ template struct StatementExpr0; // expected-note{{instantiation}} // __builtin_shufflevector // --------------------------------------------------------------------- typedef __attribute__(( ext_vector_type(2) )) double double2; + template struct ShuffleVector0 { void f(T t, U u, double2 a, double2 b) { @@ -85,3 +86,17 @@ struct ShuffleVector0 { template struct ShuffleVector0; template struct ShuffleVector0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// __builtin_choose_expr +// --------------------------------------------------------------------- +template +struct Choose0 { + void f(T t, U u) { + Result r = __builtin_choose_expr(Cond, t, u); // expected-error{{lvalue}} + } +}; + +template struct Choose0; +template struct Choose0; +template struct Choose0; // expected-note{{instantiation}}