diff options
| author | Nate Begeman <natebegeman@mac.com> | 2009-08-09 17:55:44 +0000 |
|---|---|---|
| committer | Nate Begeman <natebegeman@mac.com> | 2009-08-09 17:55:44 +0000 |
| commit | a96114ed087b924b9e8c912dacf364d5738666be (patch) | |
| tree | 149994da557bc5b4cd714afac00666b9ac2a0cfc /clang/lib/Sema | |
| parent | f4c2eee251597e552e83685ba634896aeb390130 (diff) | |
| download | bcm5719-llvm-a96114ed087b924b9e8c912dacf364d5738666be.tar.gz bcm5719-llvm-a96114ed087b924b9e8c912dacf364d5738666be.zip | |
AltiVec-style vector initializer syntax, vec4 a = (vec4)(a, b, c, d);
In addition to being defined by the AltiVec PIM, this is also the vector
initializer syntax used by OpenCL, so that vector literals are compatible
with macro arguments.
llvm-svn: 78535
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 16 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 83 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 45 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateExpr.cpp | 16 |
4 files changed, 147 insertions, 13 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 4f7ae7ec0d1..e183e3a4968 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -50,6 +50,7 @@ namespace clang { class Stmt; class Expr; class InitListExpr; + class ParenListExpr; class DesignatedInitExpr; class CallExpr; class DeclRefExpr; @@ -1484,7 +1485,10 @@ public: virtual OwningExprResult ActOnCharacterConstant(const Token &); virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, ExprArg Val); - + virtual OwningExprResult ActOnParenListExpr(SourceLocation L, + SourceLocation R, + MultiExprArg Val); + /// ActOnStringLiteral - The specified tokens were lexed as pasted string /// fragments (e.g. "foo" "bar" L"baz"). virtual OwningExprResult ActOnStringLiteral(const Token *Toks, @@ -1545,8 +1549,14 @@ public: SourceLocation *CommaLocs, SourceLocation RParenLoc); - virtual OwningExprResult ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, - SourceLocation RParenLoc, ExprArg Op); + virtual OwningExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, + TypeTy *Ty, SourceLocation RParenLoc, + ExprArg Op); + + OwningExprResult ConvertParenListExpr(Scope *S, ParenListExpr *E); + OwningExprResult ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc, + SourceLocation RParenLoc, + ParenListExpr *E, QualType Ty); virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f00ab5412d3..23e58de68c9 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1918,7 +1918,8 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc, << LHSExp->getSourceRange() << RHSExp->getSourceRange()); } // C99 6.5.2.1p1 - if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent()) + if (!(IndexExpr->getType()->isIntegerType() && + IndexExpr->getType()->isScalarType()) && !IndexExpr->isTypeDependent()) return ExprError(Diag(LLoc, diag::err_typecheck_subscript_not_integer) << IndexExpr->getSourceRange()); @@ -2114,6 +2115,11 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, Expr *BaseExpr = Base.takeAs<Expr>(); assert(BaseExpr && "no record expression"); + // If BaseExpr is a ParenListExpr then convert it into a standard + // paren expr since this is not an altivec initializer. + if (ParenListExpr *PE = dyn_cast<ParenListExpr>(BaseExpr)) + BaseExpr = ConvertParenListExpr(S, PE).takeAs<Expr>(); + // Perform default conversions. DefaultFunctionArrayConversion(BaseExpr); @@ -2689,6 +2695,11 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, FunctionDecl *FDecl = NULL; NamedDecl *NDecl = NULL; DeclarationName UnqualifiedName; + + // If the function is a ParenListExpr, then convert it into a standard + // paren expr since this is not an altivec initializer. + if (ParenListExpr *PE = dyn_cast<ParenListExpr>(Fn)) + Fn = ConvertParenListExpr(S, PE).takeAs<Expr>(); if (getLangOptions().CPlusPlus) { // Determine whether this is a dependent call inside a C++ template, @@ -3090,7 +3101,7 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) { } Action::OwningExprResult -Sema::ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, +Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty, SourceLocation RParenLoc, ExprArg Op) { CastExpr::CastKind Kind = CastExpr::CK_Unknown; @@ -3099,6 +3110,10 @@ Sema::ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, Expr *castExpr = Op.takeAs<Expr>(); QualType castType = QualType::getFromOpaquePtr(Ty); + + // If the Expr being casted is a ParenListExpr, handle it specially. + if (ParenListExpr *PE = dyn_cast<ParenListExpr>(castExpr)) + return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, PE, castType); if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr, Kind)) @@ -3108,6 +3123,68 @@ Sema::ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, LParenLoc, RParenLoc)); } +/// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence +/// of comma binary operators. +Action::OwningExprResult +Sema::ConvertParenListExpr(Scope *S, ParenListExpr *E) { + OwningExprResult Result(*this, E->getExpr(0)); + + for (unsigned i = 1, e = E->getNumExprs(); i != e && !Result.isInvalid(); ++i) + Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, move(Result), + Owned(E->getExpr(i))); + return move(Result); +} + +Action::OwningExprResult +Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc, + SourceLocation RParenLoc, + ParenListExpr *E, QualType Ty) { + // If this is an altivec initializer, '(' type ')' '(' init, ..., init ')' + // then handle it as such. + if (getLangOptions().AltiVec && Ty->isVectorType()) { + if (E->getNumExprs() == 0) { + Diag(E->getExprLoc(), diag::err_altivec_empty_initializer); + return ExprError(); + } + + llvm::SmallVector<Expr *, 8> initExprs; + for (unsigned i = 0, e = E->getNumExprs(); i != e; ++i) + initExprs.push_back(E->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(LParenLoc, &initExprs[0], + initExprs.size(), RParenLoc); + E->setType(Ty); + return ActOnCompoundLiteral(LParenLoc, Ty.getAsOpaquePtr(), RParenLoc, + Owned(E)); + } else { + // This is not an AltiVec-style cast, so turn the ParenListExpr into a + // sequence of BinOp comma operators. + OwningExprResult Result = ConvertParenListExpr(S, E); + Expr *castExpr = (Expr *)Result.get(); + CastExpr::CastKind Kind = CastExpr::CK_Unknown; + + if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty, castExpr, Kind)) + return ExprError(); + + return Owned(new (Context) CStyleCastExpr(Ty.getNonReferenceType(), + CastExpr::CK_Unknown, + Result.takeAs<Expr>(), Ty, + LParenLoc, RParenLoc)); + } +} + +Action::OwningExprResult Sema::ActOnParenListExpr(SourceLocation L, + SourceLocation R, + MultiExprArg Val) { + unsigned nexprs = Val.size(); + Expr **exprs = reinterpret_cast<Expr**>(Val.release()); + assert((exprs != 0) && "ActOnParenListExpr() missing expr list"); + Expr *expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R); + return Owned(expr); +} + /// Note that lhs is not null here, even if this is the gnu "x ?: y" extension. /// In that case, lhs = cond. /// C99 6.5.15 @@ -3132,6 +3209,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, } // Now check the two expressions. + if (LHSTy->isVectorType() || RHSTy->isVectorType()) + return CheckVectorOperands(QuestionLoc, LHS, RHS); // If both operands have arithmetic type, do the usual arithmetic conversions // to find a common type: C99 6.5.15p3,5. diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 29113822f73..1e564ce45fb 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -805,16 +805,47 @@ void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &StructuredIndex) { if (Index < IList->getNumInits()) { const VectorType *VT = DeclType->getAsVectorType(); - int maxElements = VT->getNumElements(); + unsigned maxElements = VT->getNumElements(); + unsigned numEltsInit = 0; QualType elementType = VT->getElementType(); - for (int i = 0; i < maxElements; ++i) { - // Don't attempt to go past the end of the init list - if (Index >= IList->getNumInits()) - break; - CheckSubElementType(IList, elementType, Index, - StructuredList, StructuredIndex); + if (!SemaRef.getLangOptions().OpenCL) { + for (unsigned i = 0; i < maxElements; ++i, ++numEltsInit) { + // Don't attempt to go past the end of the init list + if (Index >= IList->getNumInits()) + break; + CheckSubElementType(IList, elementType, Index, + StructuredList, StructuredIndex); + } + } else { + // OpenCL initializers allows vectors to be constructed from vectors. + for (unsigned i = 0; i < maxElements; ++i) { + // Don't attempt to go past the end of the init list + if (Index >= IList->getNumInits()) + break; + QualType IType = IList->getInit(Index)->getType(); + if (!IType->isVectorType()) { + CheckSubElementType(IList, elementType, Index, + StructuredList, StructuredIndex); + ++numEltsInit; + } else { + const VectorType *IVT = IType->getAsVectorType(); + unsigned numIElts = IVT->getNumElements(); + QualType VecType = SemaRef.Context.getExtVectorType(elementType, + numIElts); + CheckSubElementType(IList, VecType, Index, + StructuredList, StructuredIndex); + numEltsInit += numIElts; + } + } } + + // OpenCL & AltiVec require all elements to be initialized. + if (numEltsInit != maxElements) + if (SemaRef.getLangOptions().OpenCL || SemaRef.getLangOptions().AltiVec) + SemaRef.Diag(IList->getSourceRange().getBegin(), + diag::err_vector_incorrect_num_initializers) + << (numEltsInit < maxElements) << maxElements << numEltsInit; } } diff --git a/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp b/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp index 186c98cf53e..7a09210fe04 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -639,6 +639,20 @@ TemplateExprInstantiator::VisitInitListExpr(InitListExpr *E) { } Sema::OwningExprResult +TemplateExprInstantiator::VisitParenListExpr(ParenListExpr *E) { + ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef); + for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) { + OwningExprResult Init = Visit(E->getExpr(I)); + if (Init.isInvalid()) + return SemaRef.ExprError(); + Inits.push_back(Init.takeAs<Expr>()); + } + + return SemaRef.ActOnParenListExpr(E->getLParenLoc(), E->getRParenLoc(), + move_arg(Inits)); +} + +Sema::OwningExprResult TemplateExprInstantiator::VisitDesignatedInitExpr(DesignatedInitExpr *E) { Designation Desig; @@ -886,7 +900,7 @@ TemplateExprInstantiator::VisitCStyleCastExpr(CStyleCastExpr *E) { if (SubExpr.isInvalid()) return SemaRef.ExprError(); - return SemaRef.ActOnCastExpr(E->getLParenLoc(), + return SemaRef.ActOnCastExpr(/*Scope=*/0, E->getLParenLoc(), ExplicitTy.getAsOpaquePtr(), E->getRParenLoc(), move(SubExpr)); |

