diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-07-01 22:22:54 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-07-01 22:22:54 +0000 |
commit | 707f101d3302b76ee01e8ca29b1a61f081137b9f (patch) | |
tree | 0d3655ebdc866eb3f0ff928ca83b9405163666e1 /lib/Sema/SemaExpr.cpp | |
parent | 31862ba5ea70b1f2c81d03f8a0100b61cd6f06f6 (diff) |
-Remove Sema::ActOnCastOfParenListExpr and move most of its functionality to
newly introduced Sema::BuildVectorLiteral.
-Make Sema::ActOnCastExpr handle a vector initializer both when the cast'ed expression
is a ParenListExpr and when it is a ParenExpr.
-Ultimately make Sema::ActOnParenOrParenListExpr independent of what the cast type was.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134274 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 174 |
1 files changed, 95 insertions, 79 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index b99076005b..af0a3db688 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4148,10 +4148,39 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, ParsedType Ty, if (!castTInfo) castTInfo = Context.getTrivialTypeSourceInfo(castType); + bool isVectorLiteral = false; + + // Check for an altivec or OpenCL literal, + // i.e. all the elements are integer constants. + ParenExpr *PE = dyn_cast<ParenExpr>(castExpr); + ParenListExpr *PLE = dyn_cast<ParenListExpr>(castExpr); + if (getLangOptions().AltiVec && castType->isVectorType() && (PE || PLE)) { + if (PLE && PLE->getNumExprs() == 0) { + Diag(PLE->getExprLoc(), diag::err_altivec_empty_initializer); + return ExprError(); + } + if (PE || PLE->getNumExprs() == 1) { + Expr *E = (PE ? PE->getSubExpr() : PLE->getExpr(0)); + if (!E->getType()->isVectorType()) + isVectorLiteral = true; + } + else + isVectorLiteral = true; + } + + // If this is a vector initializer, '(' type ')' '(' init, ..., init ')' + // then handle it as such. + if (isVectorLiteral) + return BuildVectorLiteral(LParenLoc, RParenLoc, castExpr, castTInfo); + // If the Expr being casted is a ParenListExpr, handle it specially. - if (isa<ParenListExpr>(castExpr)) - return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, castExpr, - castTInfo); + // This is not an AltiVec-style cast, so turn the ParenListExpr into a + // sequence of BinOp comma operators. + if (isa<ParenListExpr>(castExpr)) { + ExprResult Result = MaybeConvertParenListExprToParenExpr(S, castExpr); + if (Result.isInvalid()) return ExprError(); + castExpr = Result.take(); + } return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, castExpr); } @@ -4175,6 +4204,67 @@ Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, LParenLoc, RParenLoc)); } +ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, + SourceLocation RParenLoc, Expr *E, + TypeSourceInfo *TInfo) { + assert((isa<ParenListExpr>(E) || isa<ParenExpr>(E)) && + "Expected paren or paren list expression"); + + Expr **exprs; + unsigned numExprs; + Expr *subExpr; + if (ParenListExpr *PE = dyn_cast<ParenListExpr>(E)) { + exprs = PE->getExprs(); + numExprs = PE->getNumExprs(); + } else { + subExpr = cast<ParenExpr>(E)->getSubExpr(); + exprs = &subExpr; + numExprs = 1; + } + + QualType Ty = TInfo->getType(); + assert(Ty->isVectorType() && "Expected vector type"); + + llvm::SmallVector<Expr *, 8> initExprs; + // '(...)' form of vector initialization in AltiVec: the number of + // initializers must be one or must match the size of the vector. + // If a single value is specified in the initializer then it will be + // replicated to all the components of the vector + if (Ty->getAs<VectorType>()->getVectorKind() == + VectorType::AltiVecVector) { + unsigned numElems = Ty->getAs<VectorType>()->getNumElements(); + // The number of initializers must be one or must match the size of the + // vector. If a single value is specified in the initializer then it will + // be replicated to all the components of the vector + if (numExprs == 1) { + QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); + ExprResult Literal = Owned(exprs[0]); + Literal = ImpCastExprToType(Literal.take(), ElemTy, + PrepareScalarCast(*this, Literal, ElemTy)); + return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take()); + } + else if (numExprs < numElems) { + Diag(E->getExprLoc(), + diag::err_incorrect_number_of_vector_initializers); + return ExprError(); + } + else + for (unsigned i = 0, e = numExprs; i != e; ++i) + initExprs.push_back(exprs[i]); + } + else + for (unsigned i = 0, e = numExprs; i != e; ++i) + initExprs.push_back(exprs[i]); + + // FIXME: This means that pretty-printing the final AST will produce curly + // braces instead of the original commas. + InitListExpr *initE = new (Context) InitListExpr(Context, LParenLoc, + &initExprs[0], + initExprs.size(), RParenLoc); + initE->setType(Ty); + return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE); +} + /// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence /// of comma binary operators. ExprResult @@ -4194,88 +4284,14 @@ Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *expr) { return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get()); } -ExprResult -Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc, - SourceLocation RParenLoc, Expr *Op, - TypeSourceInfo *TInfo) { - ParenListExpr *PE = cast<ParenListExpr>(Op); - QualType Ty = TInfo->getType(); - bool isVectorLiteral = false; - - // Check for an altivec or OpenCL literal, - // i.e. all the elements are integer constants. - if (getLangOptions().AltiVec && Ty->isVectorType()) { - if (PE->getNumExprs() == 0) { - Diag(PE->getExprLoc(), diag::err_altivec_empty_initializer); - return ExprError(); - } - if (PE->getNumExprs() == 1) { - if (!PE->getExpr(0)->getType()->isVectorType()) - isVectorLiteral = true; - } - else - isVectorLiteral = true; - } - - // If this is a vector initializer, '(' type ')' '(' init, ..., init ')' - // then handle it as such. - if (isVectorLiteral) { - llvm::SmallVector<Expr *, 8> initExprs; - // '(...)' form of vector initialization in AltiVec: the number of - // initializers must be one or must match the size of the vector. - // If a single value is specified in the initializer then it will be - // replicated to all the components of the vector - if (Ty->getAs<VectorType>()->getVectorKind() == - VectorType::AltiVecVector) { - unsigned numElems = Ty->getAs<VectorType>()->getNumElements(); - // The number of initializers must be one or must match the size of the - // vector. If a single value is specified in the initializer then it will - // be replicated to all the components of the vector - if (PE->getNumExprs() == 1) { - QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); - ExprResult Literal = Owned(PE->getExpr(0)); - Literal = ImpCastExprToType(Literal.take(), ElemTy, - PrepareScalarCast(*this, Literal, ElemTy)); - return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take()); - } - else if (PE->getNumExprs() < numElems) { - Diag(PE->getExprLoc(), - diag::err_incorrect_number_of_vector_initializers); - return ExprError(); - } - else - for (unsigned i = 0, e = PE->getNumExprs(); i != e; ++i) - initExprs.push_back(PE->getExpr(i)); - } - else - for (unsigned i = 0, e = PE->getNumExprs(); i != e; ++i) - initExprs.push_back(PE->getExpr(i)); - - // FIXME: This means that pretty-printing the final AST will produce curly - // braces instead of the original commas. - InitListExpr *E = new (Context) InitListExpr(Context, LParenLoc, - &initExprs[0], - initExprs.size(), RParenLoc); - E->setType(Ty); - return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, E); - } else { - // This is not an AltiVec-style cast, so turn the ParenListExpr into a - // sequence of BinOp comma operators. - ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Op); - if (Result.isInvalid()) return ExprError(); - return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Result.take()); - } -} - ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L, SourceLocation R, - MultiExprArg Val, - ParsedType TypeOfCast) { + MultiExprArg Val) { unsigned nexprs = Val.size(); Expr **exprs = reinterpret_cast<Expr**>(Val.release()); assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list"); Expr *expr; - if (nexprs == 1 && TypeOfCast && !TypeIsVectorType(TypeOfCast)) + if (nexprs == 1) expr = new (Context) ParenExpr(L, R, exprs[0]); else expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R, |