Author: abataev Date: Mon Dec 28 01:25:51 2015 New Revision: 256487 URL: http://llvm.org/viewvc/llvm-project?rev=256487&view=rev Log: [OPENMP 4.5] Sema/parsing support for extended format of 'schedule' clause. OpenMP 4.0-3.1 supports the next format of ‘schedule’ clause: schedule(kind[, chunk_size]) Where kind can be one of ‘static’, ‘dynamic’, ‘guided’, ‘auto’ or ‘runtime’. OpenMP 4.5 defines the format: schedule([modifier [, modifier]:]kind[, chunk_size]) Modifier can be one of ‘monotonic’, ‘nonmonotonic’ or ‘simd’.
Modified: cfe/trunk/include/clang/AST/OpenMPClause.h cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Basic/OpenMPKinds.def cfe/trunk/include/clang/Basic/OpenMPKinds.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/AST/StmtPrinter.cpp cfe/trunk/lib/Basic/OpenMPKinds.cpp cfe/trunk/lib/Parse/ParseOpenMP.cpp cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/lib/Sema/TreeTransform.h cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp cfe/trunk/test/OpenMP/for_schedule_messages.cpp cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp Modified: cfe/trunk/include/clang/AST/OpenMPClause.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/OpenMPClause.h (original) +++ cfe/trunk/include/clang/AST/OpenMPClause.h Mon Dec 28 01:25:51 2015 @@ -664,6 +664,11 @@ class OMPScheduleClause : public OMPClau SourceLocation LParenLoc; /// \brief A kind of the 'schedule' clause. OpenMPScheduleClauseKind Kind; + /// \brief Modifiers for 'schedule' clause. + enum {FIRST, SECOND, NUM_MODIFIERS}; + OpenMPScheduleClauseModifier Modifiers[NUM_MODIFIERS]; + /// \brief Locations of modifiers. + SourceLocation ModifiersLoc[NUM_MODIFIERS]; /// \brief Start location of the schedule ind in source code. SourceLocation KindLoc; /// \brief Location of ',' (if any). @@ -678,6 +683,42 @@ class OMPScheduleClause : public OMPClau /// \param K Schedule kind. /// void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; } + /// \brief Set the first schedule modifier. + /// + /// \param M Schedule modifier. + /// + void setFirstScheduleModifier(OpenMPScheduleClauseModifier M) { + Modifiers[FIRST] = M; + } + /// \brief Set the second schedule modifier. + /// + /// \param M Schedule modifier. + /// + void setSecondScheduleModifier(OpenMPScheduleClauseModifier M) { + Modifiers[SECOND] = M; + } + /// \brief Set location of the first schedule modifier. + /// + void setFirstScheduleModifierLoc(SourceLocation Loc) { + ModifiersLoc[FIRST] = Loc; + } + /// \brief Set location of the second schedule modifier. + /// + void setSecondScheduleModifierLoc(SourceLocation Loc) { + ModifiersLoc[SECOND] = Loc; + } + /// \brief Set schedule modifier location. + /// + /// \param M Schedule modifier location. + /// + void setScheduleModifer(OpenMPScheduleClauseModifier M) { + if (Modifiers[FIRST] == OMPC_SCHEDULE_MODIFIER_unknown) + Modifiers[FIRST] = M; + else { + assert(Modifiers[SECOND] == OMPC_SCHEDULE_MODIFIER_unknown); + Modifiers[SECOND] = M; + } + } /// \brief Sets the location of '('. /// /// \param Loc Location of '('. @@ -716,15 +757,25 @@ public: /// \param Kind Schedule kind. /// \param ChunkSize Chunk size. /// \param HelperChunkSize Helper chunk size for combined directives. + /// \param M1 The first modifier applied to 'schedule' clause. + /// \param M1Loc Location of the first modifier + /// \param M2 The second modifier applied to 'schedule' clause. + /// \param M2Loc Location of the second modifier /// OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KLoc, SourceLocation CommaLoc, SourceLocation EndLoc, OpenMPScheduleClauseKind Kind, - Expr *ChunkSize, Expr *HelperChunkSize) + Expr *ChunkSize, Expr *HelperChunkSize, + OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, + OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc) { ChunkSizes[CHUNK_SIZE] = ChunkSize; ChunkSizes[HELPER_CHUNK_SIZE] = HelperChunkSize; + Modifiers[FIRST] = M1; + Modifiers[SECOND] = M2; + ModifiersLoc[FIRST] = M1Loc; + ModifiersLoc[SECOND] = M2Loc; } /// \brief Build an empty clause. @@ -734,17 +785,39 @@ public: Kind(OMPC_SCHEDULE_unknown) { ChunkSizes[CHUNK_SIZE] = nullptr; ChunkSizes[HELPER_CHUNK_SIZE] = nullptr; + Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; + Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; } /// \brief Get kind of the clause. /// OpenMPScheduleClauseKind getScheduleKind() const { return Kind; } + /// \brief Get the first modifier of the clause. + /// + OpenMPScheduleClauseModifier getFirstScheduleModifier() const { + return Modifiers[FIRST]; + } + /// \brief Get the second modifier of the clause. + /// + OpenMPScheduleClauseModifier getSecondScheduleModifier() const { + return Modifiers[SECOND]; + } /// \brief Get location of '('. /// SourceLocation getLParenLoc() { return LParenLoc; } /// \brief Get kind location. /// SourceLocation getScheduleKindLoc() { return KindLoc; } + /// \brief Get the first modifier location. + /// + SourceLocation getFirstScheduleModifierLoc() const { + return ModifiersLoc[FIRST]; + } + /// \brief Get the second modifier location. + /// + SourceLocation getSecondScheduleModifierLoc() const { + return ModifiersLoc[SECOND]; + } /// \brief Get location of ','. /// SourceLocation getCommaLoc() { return CommaLoc; } Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Dec 28 01:25:51 2015 @@ -7963,6 +7963,12 @@ def err_omp_depend_sink_source_not_allow "'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">; def err_omp_linear_ordered : Error< "'linear' clause cannot be specified along with 'ordered' clause with a parameter">; +def err_omp_unexpected_schedule_modifier : Error< + "modifier '%0' cannot be used along with modifier '%1'">; +def err_omp_schedule_nonmonotonic_static : Error< + "'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind">; +def err_omp_schedule_nonmonotonic_ordered : Error< + "'schedule' clause with 'nonmonotonic' modifier cannot be specified if an 'ordered' clause is specified">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original) +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Mon Dec 28 01:25:51 2015 @@ -90,6 +90,9 @@ #ifndef OPENMP_SCHEDULE_KIND #define OPENMP_SCHEDULE_KIND(Name) #endif +#ifndef OPENMP_SCHEDULE_MODIFIER +#define OPENMP_SCHEDULE_MODIFIER(Name) +#endif #ifndef OPENMP_DEPEND_KIND #define OPENMP_DEPEND_KIND(Name) #endif @@ -250,6 +253,11 @@ OPENMP_SCHEDULE_KIND(guided) OPENMP_SCHEDULE_KIND(auto) OPENMP_SCHEDULE_KIND(runtime) +// Modifiers for 'schedule' clause. +OPENMP_SCHEDULE_MODIFIER(monotonic) +OPENMP_SCHEDULE_MODIFIER(nonmonotonic) +OPENMP_SCHEDULE_MODIFIER(simd) + // Static attributes for 'depend' clause. OPENMP_DEPEND_KIND(in) OPENMP_DEPEND_KIND(out) @@ -413,6 +421,7 @@ OPENMP_DISTRIBUTE_CLAUSE(collapse) #undef OPENMP_TASKLOOP_CLAUSE #undef OPENMP_LINEAR_KIND #undef OPENMP_DEPEND_KIND +#undef OPENMP_SCHEDULE_MODIFIER #undef OPENMP_SCHEDULE_KIND #undef OPENMP_PROC_BIND_KIND #undef OPENMP_DEFAULT_KIND Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.h?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/OpenMPKinds.h (original) +++ cfe/trunk/include/clang/Basic/OpenMPKinds.h Mon Dec 28 01:25:51 2015 @@ -62,6 +62,15 @@ enum OpenMPScheduleClauseKind { OMPC_SCHEDULE_unknown }; +/// \brief OpenMP modifiers for 'schedule' clause. +enum OpenMPScheduleClauseModifier { + OMPC_SCHEDULE_MODIFIER_unknown = OMPC_SCHEDULE_unknown, +#define OPENMP_SCHEDULE_MODIFIER(Name) \ + OMPC_SCHEDULE_MODIFIER_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_SCHEDULE_MODIFIER_last +}; + /// \brief OpenMP attributes for 'depend' clause. enum OpenMPDependClauseKind { #define OPENMP_DEPEND_KIND(Name) \ Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Mon Dec 28 01:25:51 2015 @@ -8042,20 +8042,17 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); - OMPClause *ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, - unsigned Argument, Expr *Expr, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ArgumentLoc, - SourceLocation DelimLoc, - SourceLocation EndLoc); + OMPClause *ActOnOpenMPSingleExprWithArgClause( + OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr, + SourceLocation StartLoc, SourceLocation LParenLoc, + ArrayRef<SourceLocation> ArgumentsLoc, SourceLocation DelimLoc, + SourceLocation EndLoc); /// \brief Called on well-formed 'schedule' clause. - OMPClause *ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind, - Expr *ChunkSize, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation KindLoc, - SourceLocation CommaLoc, - SourceLocation EndLoc); + OMPClause *ActOnOpenMPScheduleClause( + OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, + OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, + SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc); OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc); Modified: cfe/trunk/lib/AST/StmtPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/lib/AST/StmtPrinter.cpp (original) +++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Dec 28 01:25:51 2015 @@ -651,8 +651,18 @@ void OMPClausePrinter::VisitOMPProcBindC } void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) { - OS << "schedule(" - << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind()); + OS << "schedule("; + if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) { + OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, + Node->getFirstScheduleModifier()); + if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) { + OS << ", "; + OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, + Node->getSecondScheduleModifier()); + } + OS << ": "; + } + OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind()); if (Node->getChunkSize()) { OS << ", "; Node->getChunkSize()->printPretty(OS, nullptr, Policy); Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original) +++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Mon Dec 28 01:25:51 2015 @@ -87,8 +87,11 @@ unsigned clang::getOpenMPSimpleClauseTyp #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_PROC_BIND_unknown); case OMPC_schedule: - return llvm::StringSwitch<OpenMPScheduleClauseKind>(Str) -#define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name) + return llvm::StringSwitch<unsigned>(Str) +#define OPENMP_SCHEDULE_KIND(Name) \ + .Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_##Name)) +#define OPENMP_SCHEDULE_MODIFIER(Name) \ + .Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_SCHEDULE_unknown); case OMPC_depend: @@ -173,12 +176,17 @@ const char *clang::getOpenMPSimpleClause case OMPC_schedule: switch (Type) { case OMPC_SCHEDULE_unknown: + case OMPC_SCHEDULE_MODIFIER_last: return "unknown"; #define OPENMP_SCHEDULE_KIND(Name) \ - case OMPC_SCHEDULE_##Name: \ - return #Name; + case OMPC_SCHEDULE_##Name: \ + return #Name; +#define OPENMP_SCHEDULE_MODIFIER(Name) \ + case OMPC_SCHEDULE_MODIFIER_##Name: \ + return #Name; #include "clang/Basic/OpenMPKinds.def" } + llvm_unreachable("Invalid OpenMP 'schedule' clause type"); case OMPC_depend: switch (Type) { case OMPC_DEPEND_unknown: @@ -188,7 +196,7 @@ const char *clang::getOpenMPSimpleClause return #Name; #include "clang/Basic/OpenMPKinds.def" } - llvm_unreachable("Invalid OpenMP 'schedule' clause type"); + llvm_unreachable("Invalid OpenMP 'depend' clause type"); case OMPC_linear: switch (Type) { case OMPC_LINEAR_unknown: Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original) +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Mon Dec 28 01:25:51 2015 @@ -675,7 +675,8 @@ OMPClause *Parser::ParseOpenMPClause(Ope /// argument like 'schedule' or 'dist_schedule'. /// /// schedule-clause: -/// 'schedule' '(' kind [',' expression ] ')' +/// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ] +/// ')' /// /// if-clause: /// 'if' '(' [ directive-name-modifier ':' ] expression ')' @@ -690,24 +691,60 @@ OMPClause *Parser::ParseOpenMPSingleExpr return nullptr; ExprResult Val; - unsigned Arg; - SourceLocation KLoc; + SmallVector<unsigned, 4> Arg; + SmallVector<SourceLocation, 4> KLoc; if (Kind == OMPC_schedule) { - Arg = getOpenMPSimpleClauseType( + enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; + Arg.resize(NumberOfElements); + KLoc.resize(NumberOfElements); + Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown; + Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown; + Arg[ScheduleKind] = OMPC_SCHEDULE_unknown; + auto KindModifier = getOpenMPSimpleClauseType( Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); - KLoc = Tok.getLocation(); + if (KindModifier > OMPC_SCHEDULE_unknown) { + // Parse 'modifier' + Arg[Modifier1] = KindModifier; + KLoc[Modifier1] = Tok.getLocation(); + if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && + Tok.isNot(tok::annot_pragma_openmp_end)) + ConsumeAnyToken(); + if (Tok.is(tok::comma)) { + // Parse ',' 'modifier' + ConsumeAnyToken(); + KindModifier = getOpenMPSimpleClauseType( + Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); + Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown + ? KindModifier + : OMPC_SCHEDULE_unknown; + KLoc[Modifier2] = Tok.getLocation(); + if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && + Tok.isNot(tok::annot_pragma_openmp_end)) + ConsumeAnyToken(); + } + // Parse ':' + if (Tok.is(tok::colon)) + ConsumeAnyToken(); + else + Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier"; + KindModifier = getOpenMPSimpleClauseType( + Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); + } + Arg[ScheduleKind] = KindModifier; + KLoc[ScheduleKind] = Tok.getLocation(); if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && Tok.isNot(tok::annot_pragma_openmp_end)) ConsumeAnyToken(); - if ((Arg == OMPC_SCHEDULE_static || Arg == OMPC_SCHEDULE_dynamic || - Arg == OMPC_SCHEDULE_guided) && + if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static || + Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic || + Arg[ScheduleKind] == OMPC_SCHEDULE_guided) && Tok.is(tok::comma)) DelimLoc = ConsumeAnyToken(); } else { assert(Kind == OMPC_if); - KLoc = Tok.getLocation(); - Arg = ParseOpenMPDirectiveKind(*this); - if (Arg != OMPD_unknown) { + KLoc.push_back(Tok.getLocation()); + Arg.push_back(ParseOpenMPDirectiveKind(*this)); + if (Arg.back() != OMPD_unknown) { ConsumeToken(); if (Tok.is(tok::colon)) DelimLoc = ConsumeToken(); Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Dec 28 01:25:51 2015 @@ -1624,6 +1624,7 @@ StmtResult Sema::ActOnOpenMPRegionEnd(St } OMPOrderedClause *OC = nullptr; + OMPScheduleClause *SC = nullptr; SmallVector<OMPLinearClause *, 4> LCs; // This is required for proper codegen. for (auto *Clause : Clauses) { @@ -1646,20 +1647,40 @@ StmtResult Sema::ActOnOpenMPRegionEnd(St // Required for proper codegen of combined directives. // TODO: add processing for other clauses. if (auto *E = cast_or_null<Expr>( - cast<OMPScheduleClause>(Clause)->getHelperChunkSize())) { - MarkDeclarationsReferencedInExpr(E); - } + cast<OMPScheduleClause>(Clause)->getHelperChunkSize())) + MarkDeclarationsReferencedInExpr(E); } - if (Clause->getClauseKind() == OMPC_ordered) + if (Clause->getClauseKind() == OMPC_schedule) + SC = cast<OMPScheduleClause>(Clause); + else if (Clause->getClauseKind() == OMPC_ordered) OC = cast<OMPOrderedClause>(Clause); else if (Clause->getClauseKind() == OMPC_linear) LCs.push_back(cast<OMPLinearClause>(Clause)); } + bool ErrorFound = false; + // OpenMP, 2.7.1 Loop Construct, Restrictions + // The nonmonotonic modifier cannot be specified if an ordered clause is + // specified. + if (SC && + (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || + SC->getSecondScheduleModifier() == + OMPC_SCHEDULE_MODIFIER_nonmonotonic) && + OC) { + Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic + ? SC->getFirstScheduleModifierLoc() + : SC->getSecondScheduleModifierLoc(), + diag::err_omp_schedule_nonmonotonic_ordered) + << SourceRange(OC->getLocStart(), OC->getLocEnd()); + ErrorFound = true; + } if (!LCs.empty() && OC && OC->getNumForLoops()) { for (auto *C : LCs) { Diag(C->getLocStart(), diag::err_omp_linear_ordered) << SourceRange(OC->getLocStart(), OC->getLocEnd()); } + ErrorFound = true; + } + if (ErrorFound) { ActOnCapturedRegionError(); return StmtError(); } @@ -5960,33 +5981,41 @@ OMPClause *Sema::ActOnOpenMPSimpleClause return Res; } +static std::string +getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, + ArrayRef<unsigned> Exclude = llvm::None) { + std::string Values; + unsigned Bound = Last >= 2 ? Last - 2 : 0; + unsigned Skipped = Exclude.size(); + auto S = Exclude.begin(), E = Exclude.end(); + for (unsigned i = First; i < Last; ++i) { + if (std::find(S, E, i) != E) { + --Skipped; + continue; + } + Values += "'"; + Values += getOpenMPSimpleClauseTypeName(K, i); + Values += "'"; + if (i == Bound - Skipped) + Values += " or "; + else if (i != Bound + 1 - Skipped) + Values += ", "; + } + return Values; +} + OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindKwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { if (Kind == OMPC_DEFAULT_unknown) { - std::string Values; static_assert(OMPC_DEFAULT_unknown > 0, "OMPC_DEFAULT_unknown not greater than 0"); - std::string Sep(", "); - for (unsigned i = 0; i < OMPC_DEFAULT_unknown; ++i) { - Values += "'"; - Values += getOpenMPSimpleClauseTypeName(OMPC_default, i); - Values += "'"; - switch (i) { - case OMPC_DEFAULT_unknown - 2: - Values += " or "; - break; - case OMPC_DEFAULT_unknown - 1: - break; - default: - Values += Sep; - break; - } - } Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) - << Values << getOpenMPClauseName(OMPC_default); + << getListOfPossibleValues(OMPC_default, /*First=*/0, + /*Last=*/OMPC_DEFAULT_unknown) + << getOpenMPClauseName(OMPC_default); return nullptr; } switch (Kind) { @@ -6010,25 +6039,10 @@ OMPClause *Sema::ActOnOpenMPProcBindClau SourceLocation LParenLoc, SourceLocation EndLoc) { if (Kind == OMPC_PROC_BIND_unknown) { - std::string Values; - std::string Sep(", "); - for (unsigned i = 0; i < OMPC_PROC_BIND_unknown; ++i) { - Values += "'"; - Values += getOpenMPSimpleClauseTypeName(OMPC_proc_bind, i); - Values += "'"; - switch (i) { - case OMPC_PROC_BIND_unknown - 2: - Values += " or "; - break; - case OMPC_PROC_BIND_unknown - 1: - break; - default: - Values += Sep; - break; - } - } Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) - << Values << getOpenMPClauseName(OMPC_proc_bind); + << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, + /*Last=*/OMPC_PROC_BIND_unknown) + << getOpenMPClauseName(OMPC_proc_bind); return nullptr; } return new (Context) @@ -6036,21 +6050,28 @@ OMPClause *Sema::ActOnOpenMPProcBindClau } OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( - OpenMPClauseKind Kind, unsigned Argument, Expr *Expr, + OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ArgumentLoc, SourceLocation DelimLoc, + ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, SourceLocation EndLoc) { OMPClause *Res = nullptr; switch (Kind) { case OMPC_schedule: + enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; + assert(Argument.size() == NumberOfElements && + ArgumentLoc.size() == NumberOfElements); Res = ActOnOpenMPScheduleClause( - static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc, - LParenLoc, ArgumentLoc, DelimLoc, EndLoc); + static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), + static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), + static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, + StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], + ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); break; case OMPC_if: - Res = - ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument), Expr, - StartLoc, LParenLoc, ArgumentLoc, DelimLoc, EndLoc); + assert(Argument.size() == 1 && ArgumentLoc.size() == 1); + Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), + Expr, StartLoc, LParenLoc, ArgumentLoc.back(), + DelimLoc, EndLoc); break; case OMPC_final: case OMPC_num_threads: @@ -6097,32 +6118,74 @@ OMPClause *Sema::ActOnOpenMPSingleExprWi return Res; } +static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, + OpenMPScheduleClauseModifier M2, + SourceLocation M1Loc, SourceLocation M2Loc) { + if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { + SmallVector<unsigned, 2> Excluded; + if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) + Excluded.push_back(M2); + if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) + Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); + if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) + Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); + S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) + << getListOfPossibleValues(OMPC_schedule, + /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, + /*Last=*/OMPC_SCHEDULE_MODIFIER_last, + Excluded) + << getOpenMPClauseName(OMPC_schedule); + return true; + } + return false; +} + OMPClause *Sema::ActOnOpenMPScheduleClause( + OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, - SourceLocation EndLoc) { + SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, + SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { + if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || + checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) + return nullptr; + // OpenMP, 2.7.1, Loop Construct, Restrictions + // Either the monotonic modifier or the nonmonotonic modifier can be specified + // but not both. + if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || + (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && + M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || + (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && + M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { + Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) + << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) + << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); + return nullptr; + } if (Kind == OMPC_SCHEDULE_unknown) { std::string Values; - std::string Sep(", "); - for (unsigned i = 0; i < OMPC_SCHEDULE_unknown; ++i) { - Values += "'"; - Values += getOpenMPSimpleClauseTypeName(OMPC_schedule, i); - Values += "'"; - switch (i) { - case OMPC_SCHEDULE_unknown - 2: - Values += " or "; - break; - case OMPC_SCHEDULE_unknown - 1: - break; - default: - Values += Sep; - break; - } + if (M1Loc.isInvalid() && M2Loc.isInvalid()) { + unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; + Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, + /*Last=*/OMPC_SCHEDULE_MODIFIER_last, + Exclude); + } else { + Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, + /*Last=*/OMPC_SCHEDULE_unknown); } Diag(KindLoc, diag::err_omp_unexpected_clause_value) << Values << getOpenMPClauseName(OMPC_schedule); return nullptr; } + // OpenMP, 2.7.1, Loop Construct, Restrictions + // The nonmonotonic modifier can only be specified with schedule(dynamic) or + // schedule(guided). + if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || + M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && + Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { + Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, + diag::err_omp_schedule_nonmonotonic_static); + return nullptr; + } Expr *ValExpr = ChunkSize; Expr *HelperValExpr = nullptr; if (ChunkSize) { @@ -6158,8 +6221,9 @@ OMPClause *Sema::ActOnOpenMPScheduleClau } } - return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, - EndLoc, Kind, ValExpr, HelperValExpr); + return new (Context) + OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, + ValExpr, HelperValExpr, M1, M1Loc, M2, M2Loc); } OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, @@ -8046,39 +8110,18 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe SourceLocation LParenLoc, SourceLocation EndLoc) { if (DSAStack->getCurrentDirective() == OMPD_ordered && DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { - std::string Values = "'"; - Values += getOpenMPSimpleClauseTypeName(OMPC_depend, OMPC_DEPEND_source); - Values += "' or '"; - Values += getOpenMPSimpleClauseTypeName(OMPC_depend, OMPC_DEPEND_sink); - Values += "'"; Diag(DepLoc, diag::err_omp_unexpected_clause_value) - << Values << getOpenMPClauseName(OMPC_depend); + << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); return nullptr; } if (DSAStack->getCurrentDirective() != OMPD_ordered && (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { - std::string Values; - std::string Sep(", "); - for (unsigned i = 0; i < OMPC_DEPEND_unknown; ++i) { - if (i == OMPC_DEPEND_source || i == OMPC_DEPEND_sink) - continue; - Values += "'"; - Values += getOpenMPSimpleClauseTypeName(OMPC_depend, i); - Values += "'"; - switch (i) { - case OMPC_DEPEND_unknown - 4: - Values += " or "; - break; - case OMPC_DEPEND_unknown - 3: - break; - default: - Values += Sep; - break; - } - } + unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; Diag(DepLoc, diag::err_omp_unexpected_clause_value) - << Values << getOpenMPClauseName(OMPC_depend); + << getListOfPossibleValues(OMPC_depend, /*First=*/0, + /*Last=*/OMPC_DEPEND_unknown, Except) + << getOpenMPClauseName(OMPC_depend); return nullptr; } SmallVector<Expr *, 8> Vars; Modified: cfe/trunk/lib/Sema/TreeTransform.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/lib/Sema/TreeTransform.h (original) +++ cfe/trunk/lib/Sema/TreeTransform.h Mon Dec 28 01:25:51 2015 @@ -1478,15 +1478,14 @@ public: /// /// By default, performs semantic analysis to build the new OpenMP clause. /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPScheduleClause(OpenMPScheduleClauseKind Kind, - Expr *ChunkSize, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation KindLoc, - SourceLocation CommaLoc, - SourceLocation EndLoc) { + OMPClause *RebuildOMPScheduleClause( + OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, + OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, + SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { return getSema().ActOnOpenMPScheduleClause( - Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc); + M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc, + CommaLoc, EndLoc); } /// \brief Build a new OpenMP 'ordered' clause. @@ -7504,7 +7503,9 @@ TreeTransform<Derived>::TransformOMPSche if (E.isInvalid()) return nullptr; return getDerived().RebuildOMPScheduleClause( + C->getFirstScheduleModifier(), C->getSecondScheduleModifier(), C->getScheduleKind(), E.get(), C->getLocStart(), C->getLParenLoc(), + C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(), C->getScheduleKindLoc(), C->getCommaLoc(), C->getLocEnd()); } Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Dec 28 01:25:51 2015 @@ -1929,9 +1929,15 @@ void OMPClauseReader::VisitOMPProcBindCl void OMPClauseReader::VisitOMPScheduleClause(OMPScheduleClause *C) { C->setScheduleKind( static_cast<OpenMPScheduleClauseKind>(Record[Idx++])); + C->setFirstScheduleModifier( + static_cast<OpenMPScheduleClauseModifier>(Record[Idx++])); + C->setSecondScheduleModifier( + static_cast<OpenMPScheduleClauseModifier>(Record[Idx++])); C->setChunkSize(Reader->Reader.ReadSubExpr()); C->setHelperChunkSize(Reader->Reader.ReadSubExpr()); C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); + C->setFirstScheduleModifierLoc(Reader->ReadSourceLocation(Record, Idx)); + C->setSecondScheduleModifierLoc(Reader->ReadSourceLocation(Record, Idx)); C->setScheduleKindLoc(Reader->ReadSourceLocation(Record, Idx)); C->setCommaLoc(Reader->ReadSourceLocation(Record, Idx)); } Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Dec 28 01:25:51 2015 @@ -1811,9 +1811,13 @@ void OMPClauseWriter::VisitOMPProcBindCl void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) { Record.push_back(C->getScheduleKind()); + Record.push_back(C->getFirstScheduleModifier()); + Record.push_back(C->getSecondScheduleModifier()); Writer->Writer.AddStmt(C->getChunkSize()); Writer->Writer.AddStmt(C->getHelperChunkSize()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); + Writer->Writer.AddSourceLocation(C->getFirstScheduleModifierLoc(), Record); + Writer->Writer.AddSourceLocation(C->getSecondScheduleModifierLoc(), Record); Writer->Writer.AddSourceLocation(C->getScheduleKindLoc(), Record); Writer->Writer.AddSourceLocation(C->getCommaLoc(), Record); } Modified: cfe/trunk/test/OpenMP/for_schedule_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_schedule_messages.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_schedule_messages.cpp (original) +++ cfe/trunk/test/OpenMP/for_schedule_messages.cpp Mon Dec 28 01:25:51 2015 @@ -13,13 +13,23 @@ template <class T, typename S, int N, in T tmain(T argc, S **argv) { #pragma omp for schedule // expected-error {{expected '(' after 'schedule'}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for schedule (monotonic // expected-error {{expected ')'}} expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-warning {{missing ':' after schedule modifier - ignoring}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic, // expected-error {{expected ')'}} expected-error {{expected 'simd' in OpenMP clause 'schedule'}} expected-warning {{missing ':' after schedule modifier - ignoring}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (simd: // expected-error {{expected ')'}} expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (monotonic, auto // expected-error {{expected ')'}} expected-warning {{missing ':' after schedule modifier - ignoring}} expected-error {{expected 'simd' in OpenMP clause 'schedule'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic: auto, // expected-error {{expected ')'}} expected-error {{'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; @@ -48,19 +58,37 @@ T tmain(T argc, S **argv) { for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}} for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic: static) // expected-error {{'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic: auto) // expected-error {{'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic: runtime) // expected-error {{'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (monotonic, nonmonotonic: auto) // expected-error {{modifier 'nonmonotonic' cannot be used along with modifier 'monotonic'}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic, monotonic: auto) // expected-error {{modifier 'monotonic' cannot be used along with modifier 'nonmonotonic'}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic, nonmonotonic: auto) // expected-error {{modifier 'nonmonotonic' cannot be used along with modifier 'nonmonotonic'}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (monotonic, monotonic: auto) // expected-error {{modifier 'monotonic' cannot be used along with modifier 'monotonic'}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic: guided) ordered // expected-error {{'schedule' clause with 'nonmonotonic' modifier cannot be specified if an 'ordered' clause is specified}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for ordered(1) schedule(nonmonotonic: dynamic) // expected-error {{'schedule' clause with 'nonmonotonic' modifier cannot be specified if an 'ordered' clause is specified}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; return argc; } int main(int argc, char **argv) { #pragma omp for schedule // expected-error {{expected '(' after 'schedule'}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; Modified: cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp (original) +++ cfe/trunk/test/OpenMP/for_simd_schedule_messages.cpp Mon Dec 28 01:25:51 2015 @@ -13,13 +13,13 @@ template <class T, typename S, int N, in T tmain(T argc, S **argv) { #pragma omp for simd schedule // expected-error {{expected '(' after 'schedule'}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; @@ -54,13 +54,13 @@ T tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp for simd schedule // expected-error {{expected '(' after 'schedule'}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; Modified: cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp (original) +++ cfe/trunk/test/OpenMP/parallel_for_schedule_messages.cpp Mon Dec 28 01:25:51 2015 @@ -13,13 +13,13 @@ template <class T, typename S, int N, in T tmain(T argc, S **argv) { #pragma omp parallel for schedule // expected-error {{expected '(' after 'schedule'}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; @@ -54,13 +54,13 @@ T tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp parallel for schedule // expected-error {{expected '(' after 'schedule'}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; Modified: cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp?rev=256487&r1=256486&r2=256487&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp (original) +++ cfe/trunk/test/OpenMP/parallel_for_simd_schedule_messages.cpp Mon Dec 28 01:25:51 2015 @@ -13,13 +13,13 @@ template <class T, typename S, int N, in T tmain(T argc, S **argv) { #pragma omp parallel for simd schedule // expected-error {{expected '(' after 'schedule'}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; @@ -54,13 +54,13 @@ T tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp parallel for simd schedule // expected-error {{expected '(' after 'schedule'}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits