[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