diff options
Diffstat (limited to 'clang/lib/Parse/ParseOpenMP.cpp')
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 98 |
1 files changed, 80 insertions, 18 deletions
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index fa418961b29..572863c164f 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -842,7 +842,7 @@ void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind, /// annot_pragma_openmp_end /// /// allocate-directive: -/// annot_pragma_openmp 'allocate' simple-variable-list +/// annot_pragma_openmp 'allocate' simple-variable-list [<clause>] /// annot_pragma_openmp_end /// /// declare-reduction-directive: @@ -897,16 +897,44 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( DeclDirectiveListParserHelper Helper(this, DKind); if (!ParseOpenMPSimpleVarList(DKind, Helper, /*AllowScopeSpecifier=*/true)) { - // The last seen token is annot_pragma_openmp_end - need to check for - // extra tokens. + SmallVector<OMPClause *, 1> Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { - Diag(Tok, diag::warn_omp_extra_tokens_at_eol) - << getOpenMPDirectiveName(DKind); - SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); + SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, + OMPC_unknown + 1> + FirstClauses(OMPC_unknown + 1); + while (Tok.isNot(tok::annot_pragma_openmp_end)) { + OpenMPClauseKind CKind = + Tok.isAnnotation() ? OMPC_unknown + : getOpenMPClauseKind(PP.getSpelling(Tok)); + Actions.StartOpenMPClause(CKind); + OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, + !FirstClauses[CKind].getInt()); + SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, + StopBeforeMatch); + FirstClauses[CKind].setInt(true); + if (Clause != nullptr) + Clauses.push_back(Clause); + if (Tok.is(tok::annot_pragma_openmp_end)) { + Actions.EndOpenMPClause(); + break; + } + // Skip ',' if any. + if (Tok.is(tok::comma)) + ConsumeToken(); + Actions.EndOpenMPClause(); + } + // The last seen token is annot_pragma_openmp_end - need to check for + // extra tokens. + if (Tok.isNot(tok::annot_pragma_openmp_end)) { + Diag(Tok, diag::warn_omp_extra_tokens_at_eol) + << getOpenMPDirectiveName(DKind); + SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); + } } // Skip the last annot_pragma_openmp_end. ConsumeAnnotationToken(); - return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers()); + return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(), + Clauses); } break; } @@ -925,9 +953,10 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = - ParseOpenMPClause(OMPD_requires, CKind, !FirstClauses[CKind].getInt()); - SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); + OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind, + !FirstClauses[CKind].getInt()); + SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, + StopBeforeMatch); FirstClauses[CKind].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); @@ -1214,15 +1243,42 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { DeclDirectiveListParserHelper Helper(this, DKind); if (!ParseOpenMPSimpleVarList(DKind, Helper, /*AllowScopeSpecifier=*/false)) { - // The last seen token is annot_pragma_openmp_end - need to check for - // extra tokens. + SmallVector<OMPClause *, 1> Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { - Diag(Tok, diag::warn_omp_extra_tokens_at_eol) - << getOpenMPDirectiveName(DKind); - SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); + SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, + OMPC_unknown + 1> + FirstClauses(OMPC_unknown + 1); + while (Tok.isNot(tok::annot_pragma_openmp_end)) { + OpenMPClauseKind CKind = + Tok.isAnnotation() ? OMPC_unknown + : getOpenMPClauseKind(PP.getSpelling(Tok)); + Actions.StartOpenMPClause(CKind); + OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, + !FirstClauses[CKind].getInt()); + SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, + StopBeforeMatch); + FirstClauses[CKind].setInt(true); + if (Clause != nullptr) + Clauses.push_back(Clause); + if (Tok.is(tok::annot_pragma_openmp_end)) { + Actions.EndOpenMPClause(); + break; + } + // Skip ',' if any. + if (Tok.is(tok::comma)) + ConsumeToken(); + Actions.EndOpenMPClause(); + } + // The last seen token is annot_pragma_openmp_end - need to check for + // extra tokens. + if (Tok.isNot(tok::annot_pragma_openmp_end)) { + Diag(Tok, diag::warn_omp_extra_tokens_at_eol) + << getOpenMPDirectiveName(DKind); + SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); + } } - DeclGroupPtrTy Res = - Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers()); + DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective( + Loc, Helper.getIdentifiers(), Clauses); Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); } SkipUntil(tok::annot_pragma_openmp_end); @@ -1506,7 +1562,7 @@ bool Parser::ParseOpenMPSimpleVarList( /// thread_limit-clause | priority-clause | grainsize-clause | /// nogroup-clause | num_tasks-clause | hint-clause | to-clause | /// from-clause | is_device_ptr-clause | task_reduction-clause | -/// in_reduction-clause +/// in_reduction-clause | allocator-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -1535,6 +1591,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_grainsize: case OMPC_num_tasks: case OMPC_hint: + case OMPC_allocator: // OpenMP [2.5, Restrictions] // At most one num_threads clause can appear on the directive. // OpenMP [2.8.1, simd construct, Restrictions] @@ -1555,6 +1612,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // At most one grainsize clause can appear on the directive. // OpenMP [2.9.2, taskloop Construct, Restrictions] // At most one num_tasks clause can appear on the directive. + // OpenMP [2.11.3, allocate Directive, Restrictions] + // At most one allocator clause can appear on the directive. if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; @@ -1722,6 +1781,9 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName, /// hint-clause: /// 'hint' '(' expression ')' /// +/// allocator-clause: +/// 'allocator' '(' expression ')' +/// OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, bool ParseOnly) { SourceLocation Loc = ConsumeToken(); |