[cfe-commits] r67145 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiate.cpp test/SemaTemplate/instantiate-expr-2.cpp
Douglas Gregor
dgregor at apple.com
Wed Mar 18 10:38:00 PDT 2009
On Mar 17, 2009, at 5:55 PM, Gabor Greif wrote:
> Author: ggreif
> Date: Tue Mar 17 19:55:04 2009
> New Revision: 67145
>
> URL: http://llvm.org/viewvc/llvm-project?rev=67145&view=rev
> Log:
> instantiate ?: expressions
>
> Modified:
> cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
> cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=67145&r1=67144&r2=67145&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Tue Mar 17
> 19:55:04 2009
> @@ -615,6 +615,7 @@
> OwningExprResult VisitUnaryOperator(UnaryOperator *E);
> OwningExprResult VisitBinaryOperator(BinaryOperator *E);
> OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
> + OwningExprResult VisitConditionalOperator(ConditionalOperator
> *E);
> OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
> OwningExprResult VisitCXXTemporaryObjectExpr
> (CXXTemporaryObjectExpr *E);
> OwningExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
> @@ -823,6 +824,34 @@
> return move(Result);
> }
>
> +Sema::OwningExprResult
> +TemplateExprInstantiator::VisitConditionalOperator
> (ConditionalOperator *E) {
> + Sema::OwningExprResult Cond = Visit(E->getCond());
> + if (Cond.isInvalid())
> + return SemaRef.ExprError();
> +
> + // FIXME: use getLHS() and cope with NULLness
> + Sema::OwningExprResult True = Visit(E->getTrueExpr());
> + if (True.isInvalid())
> + return SemaRef.ExprError();
> +
> + Sema::OwningExprResult False = Visit(E->getFalseExpr());
> + if (False.isInvalid())
> + return SemaRef.ExprError();
> +
> + Sema::OwningExprResult Result
> + = SemaRef.ActOnConditionalOp(E->getCond()->getLocEnd(),
> + E->getFalseExpr()->getLocStart(),
> + move(Cond), move(True), move
> (False));
> + if (Result.isInvalid())
> + return SemaRef.ExprError();
> +
> +/* Cond.release();
> + True.release();
> + False.release();*/
> + return move(Result);
> +}
There's an optimization we could probably do here. When none of E's
subexpressions (cond, true, false) are type-dependent, there's no
reason to call ActOnConditionalOp because there isn't any additional
type-checking it would do. So, in this case we can just skip that type-
checking and build the ConditionalOperator directly.
> Sema::OwningExprResult
> TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr
> *E) {
> bool isSizeOf = E->isSizeOf();
> @@ -832,7 +861,7 @@
> if (T->isDependentType()) {
> T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
> /*FIXME*/E->getOperatorLoc(),
> - &SemaRef.PP.getIdentifierTable
> ().get("sizeof"));
> + &SemaRef.PP.getIdentifierTable().get
> ("sizeof"));
> if (T.isNull())
> return SemaRef.ExprError();
> }
>
> Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp?rev=67145&r1=67144&r2=67145&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp (original)
> +++ cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp Tue Mar 17
> 19:55:04 2009
> @@ -65,3 +65,37 @@
> typedef N4::UnaryOpOverload<N3::Z>::type UZ;
> UZ *uz = a8;
> }
> +
> +/*
> +namespace N5 {
> + template<int I>
> + struct Lookup {
> + enum { val = I, more = val + 1 };
> + };
> +
> + template<bool B>
> + struct Cond {
> + enum Junk { is = B ? Lookup<B>::more : Lookup<Lookup<B
> +1>::more>::val };
> + };
> +
> + enum { resultT = Cond<true>::is,
> + resultF = Cond<false>::is };
> +}
> +*/
> +
> +namespace N6 {
> + template<int I>
> + struct Lookup {
> + };
> +
> + template<bool B, typename T, typename E>
> + struct Cond {
> + typedef Lookup<B ? sizeof(T) : sizeof(E)> True;
> + typedef Lookup<!B ? sizeof(T) : sizeof(E)> False;
> + };
> +
> + typedef Cond<true, int, char>::True True;
> + typedef Cond<false, int, char>::False False;
> +}
> +
With the follow-on tweak to this test case, looks good. Thanks!
- Doug
More information about the cfe-commits
mailing list