diff options
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index f1b61077b37..bf3753fd814 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -258,7 +258,7 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, /// /// clause: /// if-clause | num_threads-clause | safelen-clause | default-clause | -/// private-clause | firstprivate-clause | shared-clause +/// private-clause | firstprivate-clause | shared-clause | linear-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -301,6 +301,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_private: case OMPC_firstprivate: case OMPC_shared: + case OMPC_linear: case OMPC_copyin: Clause = ParseOpenMPVarListClause(CKind); break; @@ -392,10 +393,13 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) { /// 'firstprivate' '(' list ')' /// shared-clause: /// 'shared' '(' list ')' +/// linear-clause: +/// 'linear' '(' list [ ':' linear-step ] ')' /// OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) { SourceLocation Loc = Tok.getLocation(); SourceLocation LOpen = ConsumeToken(); + SourceLocation ColonLoc = SourceLocation(); // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, @@ -404,8 +408,10 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) { SmallVector<Expr *, 5> Vars; bool IsComma = true; - while (IsComma || (Tok.isNot(tok::r_paren) && + const bool MayHaveTail = (Kind == OMPC_linear); + while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && Tok.isNot(tok::annot_pragma_openmp_end))) { + ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail); // Parse variable ExprResult VarExpr = ParseAssignmentExpression(); if (VarExpr.isUsable()) { @@ -416,21 +422,34 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) { } // Skip ',' if any IsComma = Tok.is(tok::comma); - if (IsComma) { + if (IsComma) ConsumeToken(); - } else if (Tok.isNot(tok::r_paren) && - Tok.isNot(tok::annot_pragma_openmp_end)) { - Diag(Tok, diag::err_omp_expected_punc) - << getOpenMPClauseName(Kind); - } + else if (Tok.isNot(tok::r_paren) && + Tok.isNot(tok::annot_pragma_openmp_end) && + (!MayHaveTail || Tok.isNot(tok::colon))) + Diag(Tok, diag::err_omp_expected_punc) << getOpenMPClauseName(Kind); + } + + // Parse ':' linear-step + Expr *TailExpr = 0; + const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon); + if (MustHaveTail) { + ColonLoc = Tok.getLocation(); + ConsumeToken(); + ExprResult Tail = ParseAssignmentExpression(); + if (Tail.isUsable()) + TailExpr = Tail.take(); + else + SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch); } // Parse ')'. T.consumeClose(); - if (Vars.empty()) + if (Vars.empty() || (MustHaveTail && !TailExpr)) return 0; - return Actions.ActOnOpenMPVarListClause(Kind, Vars, Loc, LOpen, - Tok.getLocation()); + return Actions.ActOnOpenMPVarListClause(Kind, Vars, TailExpr, Loc, LOpen, + ColonLoc, Tok.getLocation()); } |