Index: clang/include/clang/AST/OpenMPClause.h =================================================================== --- clang/include/clang/AST/OpenMPClause.h +++ clang/include/clang/AST/OpenMPClause.h @@ -6195,26 +6195,43 @@ /// Location of '('. SourceLocation LParenLoc; + /// Modifiers for 'grainsize' clause. + OpenMPGrainsizeClauseModifier Modifier = OMPC_GRAINSIZE_unknown; + + /// Location of the modifier. + SourceLocation ModifierLoc; + /// Safe iteration space distance. Stmt *Grainsize = nullptr; /// Set safelen. void setGrainsize(Expr *Size) { Grainsize = Size; } + /// Sets modifier. + void setModifier(OpenMPGrainsizeClauseModifier M) { Modifier = M; } + + /// Sets modifier location. + void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } + public: /// Build 'grainsize' 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 ModifierLoc Modifier location. + /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - OMPGrainsizeClause(Expr *Size, Stmt *HelperSize, - OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc) + OMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, Expr *Size, + Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc) : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) { + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), + ModifierLoc(ModifierLoc), Grainsize(Size) { setPreInitStmt(HelperSize, CaptureRegion); } @@ -6233,6 +6250,12 @@ /// Return safe iteration space distance. Expr *getGrainsize() const { return cast_or_null(Grainsize); } + /// Gets modifier. + OpenMPGrainsizeClauseModifier getModifier() const { return Modifier; } + + /// Gets modifier location. + SourceLocation getModifierLoc() const { return ModifierLoc; } + child_range children() { return child_range(&Grainsize, &Grainsize + 1); } const_child_range children() const { Index: clang/include/clang/Basic/DiagnosticParseKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticParseKinds.td +++ clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1316,6 +1316,7 @@ def warn_pragma_extension_is_core : Warning< "OpenCL extension %0 is core feature or supported optional core feature - ignoring">, InGroup, DefaultIgnore; +def err_modifier_expected_colon : Error<"missing ':' after %0 modifier">; // OpenCL errors. def err_opencl_taking_function_address_parser : Error< Index: clang/include/clang/Basic/OpenMPKinds.h =================================================================== --- clang/include/clang/Basic/OpenMPKinds.h +++ clang/include/clang/Basic/OpenMPKinds.h @@ -181,6 +181,12 @@ OMPC_BIND_unknown }; +enum OpenMPGrainsizeClauseModifier { +#define OPENMP_GRAINSIZE_MODIFIER(Name) OMPC_GRAINSIZE_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_GRAINSIZE_unknown +}; + /// Contains 'interop' data for 'append_args' and 'init' clauses. class Expr; struct OMPInteropInfo final { Index: clang/include/clang/Basic/OpenMPKinds.def =================================================================== --- clang/include/clang/Basic/OpenMPKinds.def +++ clang/include/clang/Basic/OpenMPKinds.def @@ -65,6 +65,9 @@ #ifndef OPENMP_BIND_KIND #define OPENMP_BIND_KIND(Name) #endif +#ifndef OPENMP_GRAINSIZE_MODIFIER +#define OPENMP_GRAINSIZE_MODIFIER(Name) +#endif // Static attributes for 'schedule' clause. OPENMP_SCHEDULE_KIND(static) @@ -167,6 +170,10 @@ OPENMP_BIND_KIND(parallel) OPENMP_BIND_KIND(thread) +// Modifiers for the 'grainsize' clause. +OPENMP_GRAINSIZE_MODIFIER(strict) + +#undef OPENMP_GRAINSIZE_MODIFIER #undef OPENMP_BIND_KIND #undef OPENMP_ADJUST_ARGS_KIND #undef OPENMP_REDUCTION_MODIFIER Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -11661,8 +11661,10 @@ SourceLocation LParenLoc = SourceLocation(), Expr *NumForLoops = nullptr); /// Called on well-formed 'grainsize' clause. - OMPClause *ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, + OMPClause *ActOnOpenMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, + Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc); /// Called on well-formed 'num_tasks' clause. OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, Index: clang/lib/AST/OpenMPClause.cpp =================================================================== --- clang/lib/AST/OpenMPClause.cpp +++ clang/lib/AST/OpenMPClause.cpp @@ -1905,6 +1905,11 @@ void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) { OS << "grainsize("; + OpenMPGrainsizeClauseModifier Modifier = Node->getModifier(); + if (Modifier != OMPC_GRAINSIZE_unknown) { + OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier) + << ": "; + } Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0); OS << ")"; } Index: clang/lib/Basic/OpenMPKinds.cpp =================================================================== --- clang/lib/Basic/OpenMPKinds.cpp +++ clang/lib/Basic/OpenMPKinds.cpp @@ -139,6 +139,15 @@ #define OPENMP_BIND_KIND(Name) .Case(#Name, OMPC_BIND_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_BIND_unknown); + case OMPC_grainsize: { + unsigned Type = llvm::StringSwitch(Str) +#define OPENMP_GRAINSIZE_MODIFIER(Name) .Case(#Name, OMPC_GRAINSIZE_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_GRAINSIZE_unknown); + if (LangOpts.OpenMP < 51) + return OMPC_GRAINSIZE_unknown; + return Type; + } case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -178,7 +187,6 @@ case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: - case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: case OMPC_hint: @@ -406,6 +414,16 @@ #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'bind' clause type"); + case OMPC_grainsize: + switch (Type) { + case OMPC_GRAINSIZE_unknown: + return "unknown"; +#define OPENMP_GRAINSIZE_MODIFIER(Name) \ + case OMPC_GRAINSIZE_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier"); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -445,7 +463,6 @@ case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: - case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: case OMPC_hint: Index: clang/lib/Parse/ParseOpenMP.cpp =================================================================== --- clang/lib/Parse/ParseOpenMP.cpp +++ clang/lib/Parse/ParseOpenMP.cpp @@ -3164,6 +3164,8 @@ if ((CKind == OMPC_ordered || CKind == OMPC_partial) && PP.LookAhead(/*N=*/0).isNot(tok::l_paren)) Clause = ParseOpenMPClause(CKind, WrongDirective); + else if (CKind == OMPC_grainsize) + Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective); else Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective); break; @@ -3804,6 +3806,31 @@ Arg.push_back(OMPC_DEVICE_unknown); KLoc.emplace_back(); } + } else if (Kind == OMPC_grainsize) { + // Parse optional ':' + OpenMPGrainsizeClauseModifier Modifier = 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_GRAINSIZE_strict) { + Diag(Tok, diag::err_modifier_expected_colon) << "strict"; + // Parse modifier + ConsumeAnyToken(); + } + Arg.push_back(OMPC_GRAINSIZE_unknown); + KLoc.emplace_back(); + } + } else { + Arg.push_back(OMPC_GRAINSIZE_unknown); + KLoc.emplace_back(); + } } else { assert(Kind == OMPC_if); KLoc.push_back(Tok.getLocation()); @@ -3826,7 +3853,8 @@ bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) || (Kind == OMPC_dist_schedule && DelimLoc.isValid()) || - Kind == OMPC_if || Kind == OMPC_device; + Kind == OMPC_if || Kind == OMPC_device || + Kind == OMPC_grainsize; if (NeedAnExpression) { SourceLocation ELoc = Tok.getLocation(); ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast)); Index: clang/lib/Sema/SemaOpenMP.cpp =================================================================== --- clang/lib/Sema/SemaOpenMP.cpp +++ clang/lib/Sema/SemaOpenMP.cpp @@ -15085,9 +15085,6 @@ case OMPC_priority: Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); break; - case OMPC_grainsize: - Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); - break; case OMPC_num_tasks: Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); break; @@ -15115,6 +15112,7 @@ case OMPC_align: Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); break; + case OMPC_grainsize: case OMPC_device: case OMPC_if: case OMPC_default: @@ -16810,6 +16808,13 @@ static_cast(Argument.back()), Expr, StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); break; + case OMPC_grainsize: + assert(Argument.size() == 1 && ArgumentLoc.size() == 1 && + "Modifier for grainsize clause and its location are expected."); + Res = ActOnOpenMPGrainsizeClause( + static_cast(Argument.back()), Expr, + StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); + break; case OMPC_final: case OMPC_num_threads: case OMPC_safelen: @@ -16855,7 +16860,6 @@ case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: - case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: case OMPC_hint: @@ -22277,10 +22281,21 @@ StartLoc, LParenLoc, EndLoc); } -OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { +OMPClause *Sema::ActOnOpenMPGrainsizeClause( + OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc) { + assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && + "Unexpected grainsize modifier in OpenMP < 51."); + + if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) { + std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0, + OMPC_GRAINSIZE_unknown); + Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) + << Values << getOpenMPClauseName(OMPC_grainsize); + return nullptr; + } + Expr *ValExpr = Grainsize; Stmt *HelperValStmt = nullptr; OpenMPDirectiveKind CaptureRegion = OMPD_unknown; @@ -22288,14 +22303,16 @@ // OpenMP [2.9.2, taskloop Constrcut] // The parameter of the grainsize clause must be a positive integer // expression. - if (!isNonNegativeIntegerValue( - ValExpr, *this, OMPC_grainsize, - /*StrictlyPositive=*/true, /*BuildCapture=*/true, - DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) + if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, + /*StrictlyPositive=*/true, + /*BuildCapture=*/true, + DSAStack->getCurrentDirective(), + &CaptureRegion, &HelperValStmt)) return nullptr; - return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, - StartLoc, LParenLoc, EndLoc); + return new (Context) + OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, + StartLoc, LParenLoc, ModifierLoc, EndLoc); } OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -2051,11 +2051,13 @@ /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPGrainsizeClause(Expr *Grainsize, SourceLocation StartLoc, + OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, + Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPGrainsizeClause(Grainsize, StartLoc, LParenLoc, - EndLoc); + return getSema().ActOnOpenMPGrainsizeClause(Modifier, Device, StartLoc, + LParenLoc, ModifierLoc, EndLoc); } /// Build a new OpenMP 'num_tasks' clause. @@ -10310,7 +10312,8 @@ if (E.isInvalid()) return nullptr; return getDerived().RebuildOMPGrainsizeClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); + C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(), + C->getModifierLoc(), C->getEndLoc()); } template Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -10751,7 +10751,9 @@ void OMPClauseReader::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { VisitOMPClauseWithPreInit(C); + C->setModifier(Record.readEnum()); C->setGrainsize(Record.readSubExpr()); + C->setModifierLoc(Record.readSourceLocation()); C->setLParenLoc(Record.readSourceLocation()); } Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -6787,7 +6787,9 @@ void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { VisitOMPClauseWithPreInit(C); + Record.writeEnum(C->getModifier()); Record.AddStmt(C->getGrainsize()); + Record.AddSourceLocation(C->getModifierLoc()); Record.AddSourceLocation(C->getLParenLoc()); } Index: clang/test/OpenMP/masked_taskloop_grainsize_messages.cpp =================================================================== --- clang/test/OpenMP/masked_taskloop_grainsize_messages.cpp +++ clang/test/OpenMP/masked_taskloop_grainsize_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized void foo() { } Index: clang/test/OpenMP/masked_taskloop_simd_grainsize_messages.cpp =================================================================== --- clang/test/OpenMP/masked_taskloop_simd_grainsize_messages.cpp +++ clang/test/OpenMP/masked_taskloop_simd_grainsize_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized void foo() { } Index: clang/test/OpenMP/master_taskloop_grainsize_messages.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_grainsize_messages.cpp +++ clang/test/OpenMP/master_taskloop_grainsize_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized void foo() { } Index: clang/test/OpenMP/master_taskloop_simd_grainsize_messages.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_simd_grainsize_messages.cpp +++ clang/test/OpenMP/master_taskloop_simd_grainsize_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized void foo() { } Index: clang/test/OpenMP/parallel_masked_taskloop_simd_grainsize_messages.cpp =================================================================== --- clang/test/OpenMP/parallel_masked_taskloop_simd_grainsize_messages.cpp +++ clang/test/OpenMP/parallel_masked_taskloop_simd_grainsize_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized void foo() { } Index: clang/test/OpenMP/parallel_master_taskloop_grainsize_messages.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_grainsize_messages.cpp +++ clang/test/OpenMP/parallel_master_taskloop_grainsize_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized void foo() { } Index: clang/test/OpenMP/parallel_master_taskloop_simd_grainsize_messages.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_simd_grainsize_messages.cpp +++ clang/test/OpenMP/parallel_master_taskloop_simd_grainsize_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized void foo() { } Index: clang/test/OpenMP/taskloop_grainsize_messages.cpp =================================================================== --- clang/test/OpenMP/taskloop_grainsize_messages.cpp +++ clang/test/OpenMP/taskloop_grainsize_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized void foo() { } Index: clang/test/OpenMP/taskloop_simd_grainsize_messages.cpp =================================================================== --- clang/test/OpenMP/taskloop_simd_grainsize_messages.cpp +++ clang/test/OpenMP/taskloop_simd_grainsize_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized void foo() { } Index: clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp =================================================================== --- /dev/null +++ clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp @@ -0,0 +1,142 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +template +T tmain(T argc) { + T b = argc, c, d, e, f, g; + static T a; +// CHECK: static T a; +#pragma omp taskgroup +#pragma omp taskloop grainsize(strict: N) + // CHECK-NEXT: #pragma omp taskgroup + // CHECK-NEXT: #pragma omp taskloop grainsize(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 grainsize(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 grainsize(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-LABEL: int main(int argc, char **argv) { +int main(int argc, char **argv) { + int b = argc, c, d, e, f, g; + int tid = 0; + static int a; +// CHECK: static int a; +#pragma omp taskloop grainsize(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp taskloop grainsize(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp masked taskloop grainsize(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp masked taskloop grainsize(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp masked taskloop simd grainsize(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp masked taskloop simd grainsize(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel masked taskloop grainsize(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel masked taskloop grainsize(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel masked taskloop simd grainsize(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel masked taskloop simd grainsize(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp master taskloop grainsize(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp master taskloop grainsize(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel +#pragma omp master taskloop simd grainsize(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK: #pragma omp parallel + // CHECK-NEXT: #pragma omp master taskloop simd grainsize(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel master taskloop grainsize(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel master taskloop grainsize(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + +#pragma omp parallel master taskloop simd grainsize(strict: argc) + for (int i = 0; i < 10; ++i) + foo(); + // CHECK-NEXT: #pragma omp parallel master taskloop simd grainsize(strict: argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: foo(); + + return (tmain(argc) + tmain(argv[0][0])); +} + +#endif Index: clang/test/OpenMP/taskloop_strict_modifier_messages.cpp =================================================================== --- /dev/null +++ clang/test/OpenMP/taskloop_strict_modifier_messages.cpp @@ -0,0 +1,113 @@ +// 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 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +template +int tmain(T argc, S **argv) { + T z; + #pragma omp taskloop grainsize(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 grainsize(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 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(); + + return 0; +} + +int main(int argc, char **argv) { + int z; + #pragma omp masked taskloop grainsize(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 grainsize(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 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 simd grainsize(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 grainsize(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 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 parallel masked taskloop grainsize(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 grainsize(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 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 parallel masked taskloop simd grainsize(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 grainsize(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 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 master taskloop grainsize(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 grainsize(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 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 master taskloop simd grainsize(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 grainsize(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 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 parallel master taskloop grainsize(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 grainsize(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 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 parallel master taskloop simd grainsize(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 grainsize(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 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(); + + return tmain(argc, argv); +}