diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -6486,26 +6486,43 @@ /// Location of '('. SourceLocation LParenLoc; + /// Modifiers for 'num_tasks' clause. + OpenMPNumTasksClauseModifier Modifier = OMPC_NUMTASKS_unknown; + + /// Location of the modifier. + SourceLocation ModifierLoc; + /// Safe iteration space distance. Stmt *NumTasks = nullptr; /// Set safelen. void setNumTasks(Expr *Size) { NumTasks = Size; } + /// Sets modifier. + void setModifier(OpenMPNumTasksClauseModifier M) { Modifier = M; } + + /// Sets modifier location. + void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } + public: /// Build 'num_tasks' clause. /// + /// \param Modifier Clause modifier. /// \param Size Expression associated with this clause. /// \param HelperSize Helper grainsize for the construct. /// \param CaptureRegion Innermost OpenMP region where expressions in this /// clause must be captured. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - OMPNumTasksClause(Expr *Size, Stmt *HelperSize, - OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc) + /// \param ModifierLoc Modifier location. + /// \param LParenLoc Location of '('. + OMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *Size, + Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc) : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) { + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), + ModifierLoc(ModifierLoc), NumTasks(Size) { setPreInitStmt(HelperSize, CaptureRegion); } @@ -6524,6 +6541,12 @@ /// Return safe iteration space distance. Expr *getNumTasks() const { return cast_or_null(NumTasks); } + /// Gets modifier. + OpenMPNumTasksClauseModifier getModifier() const { return Modifier; } + + /// Gets modifier location. + SourceLocation getModifierLoc() const { return ModifierLoc; } + child_range children() { return child_range(&NumTasks, &NumTasks + 1); } const_child_range children() const { diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -201,6 +201,12 @@ OMPC_GRAINSIZE_unknown }; +enum OpenMPNumTasksClauseModifier { +#define OPENMP_NUMTASKS_MODIFIER(Name) OMPC_NUMTASKS_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_NUMTASKS_unknown +}; + /// Contains 'interop' data for 'append_args' and 'init' clauses. class Expr; struct OMPInteropInfo final { diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -74,6 +74,9 @@ #ifndef OPENMP_GRAINSIZE_MODIFIER #define OPENMP_GRAINSIZE_MODIFIER(Name) #endif +#ifndef OPENMP_NUMTASKS_MODIFIER +#define OPENMP_NUMTASKS_MODIFIER(Name) +#endif // Static attributes for 'schedule' clause. OPENMP_SCHEDULE_KIND(static) @@ -187,6 +190,10 @@ // Modifiers for the 'grainsize' clause. OPENMP_GRAINSIZE_MODIFIER(strict) +// Modifiers for the 'num_tasks' clause. +OPENMP_NUMTASKS_MODIFIER(strict) + +#undef OPENMP_NUMTASKS_MODIFIER #undef OPENMP_GRAINSIZE_MODIFIER #undef OPENMP_BIND_KIND #undef OPENMP_ADJUST_ARGS_KIND diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11685,8 +11685,10 @@ SourceLocation ModifierLoc, SourceLocation EndLoc); /// Called on well-formed 'num_tasks' clause. - OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, + OMPClause *ActOnOpenMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, + Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc); /// Called on well-formed 'hint' clause. OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1931,6 +1931,11 @@ void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) { OS << "num_tasks("; + OpenMPNumTasksClauseModifier Modifier = Node->getModifier(); + if (Modifier != OMPC_NUMTASKS_unknown) { + OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier) + << ": "; + } Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0); OS << ")"; } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -158,6 +158,15 @@ return OMPC_GRAINSIZE_unknown; return Type; } + case OMPC_num_tasks: { + unsigned Type = llvm::StringSwitch(Str) +#define OPENMP_NUMTASKS_MODIFIER(Name) .Case(#Name, OMPC_NUMTASKS_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_NUMTASKS_unknown); + if (LangOpts.OpenMP < 51) + return OMPC_NUMTASKS_unknown; + return Type; + } case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -198,7 +207,6 @@ case OMPC_thread_limit: case OMPC_priority: case OMPC_nogroup: - case OMPC_num_tasks: case OMPC_hint: case OMPC_uniform: case OMPC_use_device_ptr: @@ -454,6 +462,16 @@ #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier"); + case OMPC_num_tasks: + switch (Type) { + case OMPC_NUMTASKS_unknown: + return "unknown"; +#define OPENMP_NUMTASKS_MODIFIER(Name) \ + case OMPC_NUMTASKS_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier"); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -494,7 +512,6 @@ case OMPC_thread_limit: case OMPC_priority: case OMPC_nogroup: - case OMPC_num_tasks: case OMPC_hint: case OMPC_uniform: case OMPC_use_device_ptr: diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -3226,7 +3226,7 @@ if ((CKind == OMPC_ordered || CKind == OMPC_partial) && PP.LookAhead(/*N=*/0).isNot(tok::l_paren)) Clause = ParseOpenMPClause(CKind, WrongDirective); - else if (CKind == OMPC_grainsize) + else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks) Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective); else Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective); @@ -3900,6 +3900,33 @@ Arg.push_back(OMPC_GRAINSIZE_unknown); KLoc.emplace_back(); } + } else if (Kind == OMPC_num_tasks) { + // Parse optional ':' + OpenMPNumTasksClauseModifier Modifier = + static_cast(getOpenMPSimpleClauseType( + Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), + getLangOpts())); + if (getLangOpts().OpenMP >= 51) { + if (NextToken().is(tok::colon)) { + Arg.push_back(Modifier); + KLoc.push_back(Tok.getLocation()); + // Parse modifier + ConsumeAnyToken(); + // Parse ':' + ConsumeAnyToken(); + } else { + if (Modifier == OMPC_NUMTASKS_strict) { + Diag(Tok, diag::err_modifier_expected_colon) << "strict"; + // Parse modifier + ConsumeAnyToken(); + } + Arg.push_back(OMPC_NUMTASKS_unknown); + KLoc.emplace_back(); + } + } else { + Arg.push_back(OMPC_NUMTASKS_unknown); + KLoc.emplace_back(); + } } else { assert(Kind == OMPC_if); KLoc.push_back(Tok.getLocation()); @@ -3923,7 +3950,7 @@ bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) || (Kind == OMPC_dist_schedule && DelimLoc.isValid()) || Kind == OMPC_if || Kind == OMPC_device || - Kind == OMPC_grainsize; + Kind == OMPC_grainsize || Kind == OMPC_num_tasks; if (NeedAnExpression) { SourceLocation ELoc = Tok.getLocation(); ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast)); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -15110,9 +15110,6 @@ case OMPC_priority: Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); break; - case OMPC_num_tasks: - Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); - break; case OMPC_hint: Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); break; @@ -15138,6 +15135,7 @@ Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); break; case OMPC_grainsize: + case OMPC_num_tasks: case OMPC_device: case OMPC_if: case OMPC_default: @@ -16884,6 +16882,13 @@ static_cast(Argument.back()), Expr, StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); break; + case OMPC_num_tasks: + assert(Argument.size() == 1 && ArgumentLoc.size() == 1 && + "Modifier for num_tasks clause and its location are expected."); + Res = ActOnOpenMPNumTasksClause( + static_cast(Argument.back()), Expr, + StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); + break; case OMPC_final: case OMPC_num_threads: case OMPC_safelen: @@ -16930,7 +16935,6 @@ case OMPC_thread_limit: case OMPC_priority: case OMPC_nogroup: - case OMPC_num_tasks: case OMPC_hint: case OMPC_unknown: case OMPC_uniform: @@ -22393,10 +22397,21 @@ StartLoc, LParenLoc, ModifierLoc, EndLoc); } -OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { +OMPClause *Sema::ActOnOpenMPNumTasksClause( + OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc) { + assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && + "Unexpected num_tasks modifier in OpenMP < 51."); + + if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) { + std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0, + OMPC_NUMTASKS_unknown); + Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) + << Values << getOpenMPClauseName(OMPC_num_tasks); + return nullptr; + } + Expr *ValExpr = NumTasks; Stmt *HelperValStmt = nullptr; OpenMPDirectiveKind CaptureRegion = OMPD_unknown; @@ -22410,8 +22425,9 @@ DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) return nullptr; - return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, - StartLoc, LParenLoc, EndLoc); + return new (Context) + OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, + StartLoc, LParenLoc, ModifierLoc, EndLoc); } OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2064,11 +2064,13 @@ /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, + OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, + Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPNumTasksClause(NumTasks, StartLoc, LParenLoc, - EndLoc); + return getSema().ActOnOpenMPNumTasksClause(Modifier, NumTasks, StartLoc, + LParenLoc, ModifierLoc, EndLoc); } /// Build a new OpenMP 'hint' clause. @@ -10363,7 +10365,8 @@ if (E.isInvalid()) return nullptr; return getDerived().RebuildOMPNumTasksClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); + C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(), + C->getModifierLoc(), C->getEndLoc()); } template diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -10792,7 +10792,9 @@ void OMPClauseReader::VisitOMPNumTasksClause(OMPNumTasksClause *C) { VisitOMPClauseWithPreInit(C); + C->setModifier(Record.readEnum()); C->setNumTasks(Record.readSubExpr()); + C->setModifierLoc(Record.readSourceLocation()); C->setLParenLoc(Record.readSourceLocation()); } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6798,7 +6798,9 @@ void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) { VisitOMPClauseWithPreInit(C); + Record.writeEnum(C->getModifier()); Record.AddStmt(C->getNumTasks()); + Record.AddSourceLocation(C->getModifierLoc()); Record.AddSourceLocation(C->getLParenLoc()); } diff --git a/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp b/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp --- a/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp +++ b/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp @@ -56,6 +56,46 @@ // CHECK-NEXT: #pragma omp cancel taskgroup // CHECK-NEXT: #pragma omp cancellation point taskgroup // CHECK-NEXT: foo(); + +#pragma omp taskgroup +#pragma omp taskloop num_tasks(strict: N) + // CHECK: #pragma omp taskgroup + // CHECK-NEXT: #pragma omp taskloop num_tasks(strict: N) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp parallel +#pragma omp taskloop num_tasks(strict: N) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) { +#pragma omp cancel taskgroup +#pragma omp cancellation point taskgroup + foo(); + } + // CHECK-NEXT: #pragma omp parallel + // CHECK-NEXT: #pragma omp taskloop num_tasks(strict: N) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) { + // CHECK-NEXT: #pragma omp cancel taskgroup + // CHECK-NEXT: #pragma omp cancellation point taskgroup + // CHECK-NEXT: foo(); return T(); } @@ -136,6 +176,77 @@ // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); +#pragma omp taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp masked taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp masked taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp masked taskloop simd num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp masked taskloop simd num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel masked taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel masked taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel masked taskloop simd num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel masked taskloop simd num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp master taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp master taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp master taskloop simd num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp master taskloop simd num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel master taskloop num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel master taskloop num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel master taskloop simd num_tasks(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel master taskloop simd num_tasks(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + return (tmain(argc) + tmain(argv[0][0])); } diff --git a/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp b/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp --- a/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp +++ b/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 -ferror-limit 150 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -ferror-limit 150 %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 -fopenmp-simd -ferror-limit 150 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -fopenmp-simd -ferror-limit 150 %s -Wuninitialized void foo() { } @@ -23,7 +23,15 @@ #pragma omp taskloop grainsize(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'grainsize'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} for (int i = 0; i < 10; ++i) foo(); - + #pragma omp taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); return 0; } @@ -108,6 +116,83 @@ #pragma omp parallel master taskloop simd grainsize(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'grainsize'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} for (int i = 0; i < 10; ++i) foo(); - + #pragma omp masked taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp masked taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp masked taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp masked taskloop simd num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp masked taskloop simd num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp masked taskloop simd num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp parallel masked taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel masked taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel masked taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp parallel masked taskloop simd num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel masked taskloop simd num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel masked taskloop simd num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp master taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp master taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp master taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp master taskloop simd num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp master taskloop simd num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp master taskloop simd num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + #pragma omp parallel master taskloop simd num_tasks(strict 10) // omp51-error {{missing ':' after strict modifier}} omp50-error {{use of undeclared identifier 'strict'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop simd num_tasks(aa 10) // omp51-error {{use of undeclared identifier 'aa'}} omp51-error {{expected ')'}} omp51-note {{to match this '('}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp parallel master taskloop simd num_tasks(aa: 10) // omp51-error {{expected 'strict' in OpenMP clause 'num_tasks'}} omp50-error {{use of undeclared identifier 'aa'}} omp50-error {{expected ')'}} omp50-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); return tmain(argc, argv); } diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -246,9 +246,18 @@ def OMPC_NoGroup : Clause<"nogroup"> { let clangClass = "OMPNogroupClause"; } + +def OMP_NUMTASKS_Strict : ClauseVal<"strict", 1, 1> {} +def OMP_NUMTASKS_Unknown : ClauseVal<"unkonwn", 2, 0> { let isDefault = 1; } + def OMPC_NumTasks : Clause<"num_tasks"> { let clangClass = "OMPNumTasksClause"; let flangClass = "ScalarIntExpr"; + let enumClauseValue = "NumTasksType"; + let allowedClauseValues = [ + OMP_NUMTASKS_Strict, + OMP_NUMTASKS_Unknown + ]; } def OMPC_Hint : Clause<"hint"> { let clangClass = "OMPHintClause";