/// 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);
}
/// Return safe iteration space distance.
Expr *getNumTasks() const { return cast_or_null<Expr>(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 {
#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)
// 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
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 {
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,
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 << ")";
}
return OMPC_GRAINSIZE_unknown;
return Type;
}
+ case OMPC_num_tasks: {
+ unsigned Type = llvm::StringSwitch<unsigned>(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:
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:
#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:
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:
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);
Arg.push_back(OMPC_GRAINSIZE_unknown);
KLoc.emplace_back();
}
+ } else if (Kind == OMPC_num_tasks) {
+ // Parse optional <num_tasks modifier> ':'
+ OpenMPNumTasksClauseModifier Modifier =
+ static_cast<OpenMPNumTasksClauseModifier>(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());
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));
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;
Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_grainsize:
+ case OMPC_num_tasks:
case OMPC_device:
case OMPC_if:
case OMPC_default:
static_cast<OpenMPGrainsizeClauseModifier>(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<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
+ StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
+ break;
case OMPC_final:
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_thread_limit:
case OMPC_priority:
case OMPC_nogroup:
- case OMPC_num_tasks:
case OMPC_hint:
case OMPC_unknown:
case OMPC_uniform:
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;
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,
///
/// 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.
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 <typename Derived>
void OMPClauseReader::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
VisitOMPClauseWithPreInit(C);
+ C->setModifier(Record.readEnum<OpenMPNumTasksClauseModifier>());
C->setNumTasks(Record.readSubExpr());
+ C->setModifierLoc(Record.readSourceLocation());
C->setLParenLoc(Record.readSourceLocation());
}
void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
VisitOMPClauseWithPreInit(C);
+ Record.writeEnum(C->getModifier());
Record.AddStmt(C->getNumTasks());
+ Record.AddSourceLocation(C->getModifierLoc());
Record.AddSourceLocation(C->getLParenLoc());
}
// 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();
}
// 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<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
}
-// 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() {
}
#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;
}
#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);
}
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";