diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Parse/Parser.h | 6 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 54 | ||||
| -rw-r--r-- | clang/test/Parser/vector-cast-define.cl | 10 | 
3 files changed, 65 insertions, 5 deletions
| diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index e1d395c85f6..ff099cce179 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1449,10 +1449,12 @@ private:    ExprResult ParseCastExpression(bool isUnaryExpression,                                   bool isAddressOfOperand,                                   bool &NotCastExpr, -                                 TypeCastState isTypeCast); +                                 TypeCastState isTypeCast, +                                 bool isVectorLiteral = false);    ExprResult ParseCastExpression(bool isUnaryExpression,                                   bool isAddressOfOperand = false, -                                 TypeCastState isTypeCast = NotTypeCast); +                                 TypeCastState isTypeCast = NotTypeCast, +                                 bool isVectorLiteral = false);    /// Returns true if the next token cannot start an expression.    bool isNotExpressionStart(); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 4dcdfbf993e..ed7b8f33fc0 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -473,12 +473,14 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {  ///  ExprResult Parser::ParseCastExpression(bool isUnaryExpression,                                         bool isAddressOfOperand, -                                       TypeCastState isTypeCast) { +                                       TypeCastState isTypeCast, +                                       bool isVectorLiteral) {    bool NotCastExpr;    ExprResult Res = ParseCastExpression(isUnaryExpression,                                         isAddressOfOperand,                                         NotCastExpr, -                                       isTypeCast); +                                       isTypeCast, +                                       isVectorLiteral);    if (NotCastExpr)      Diag(Tok, diag::err_expected_expression);    return Res; @@ -694,7 +696,8 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {  ExprResult Parser::ParseCastExpression(bool isUnaryExpression,                                         bool isAddressOfOperand,                                         bool &NotCastExpr, -                                       TypeCastState isTypeCast) { +                                       TypeCastState isTypeCast, +                                       bool isVectorLiteral) {    ExprResult Res;    tok::TokenKind SavedKind = Tok.getKind();    NotCastExpr = false; @@ -722,6 +725,9 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,      Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,                                 isTypeCast == IsTypeCast, CastTy, RParenLoc); +    if (isVectorLiteral) +        return Res; +      switch (ParenExprType) {      case SimpleExpr:   break;    // Nothing else to do.      case CompoundStmt: break;  // Nothing else to do. @@ -2350,6 +2356,48 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,          return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);        } +      if (Tok.is(tok::l_paren)) { +        // This could be OpenCL vector Literals +        if (getLangOpts().OpenCL) +        { +          TypeResult Ty; +          { +            InMessageExpressionRAIIObject InMessage(*this, false); +            Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); +          } +          if(Ty.isInvalid()) +          { +             return ExprError(); +          } +          QualType QT = Ty.get().get().getCanonicalType(); +          if (QT->isVectorType()) +          { +            // We parsed '(' vector-type-name ')' followed by '(' + +            // Parse the cast-expression that follows it next. +            // isVectorLiteral = true will make sure we don't parse any +            // Postfix expression yet +            Result = ParseCastExpression(/*isUnaryExpression=*/false, +                                         /*isAddressOfOperand=*/false, +                                         /*isTypeCast=*/IsTypeCast, +                                         /*isVectorLiteral=*/true); + +            if (!Result.isInvalid()) { +              Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, +                                             DeclaratorInfo, CastTy, +                                             RParenLoc, Result.get()); +            } + +            // After we performed the cast we can check for postfix-expr pieces. +            if (!Result.isInvalid()) { +              Result = ParsePostfixExpressionSuffix(Result); +            } + +            return Result; +          } +        } +      } +        if (ExprType == CastExpr) {          // We parsed '(' type-name ')' and the thing after it wasn't a '{'. diff --git a/clang/test/Parser/vector-cast-define.cl b/clang/test/Parser/vector-cast-define.cl new file mode 100644 index 00000000000..ec4eba7a784 --- /dev/null +++ b/clang/test/Parser/vector-cast-define.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// expected-no-diagnostics + +typedef int int3 __attribute__((ext_vector_type(3))); + +void test() +{ +    int index = (int3)(1, 2, 3).x * (int3)(3, 2, 1).y; +} + | 

