From ab9eac762c35068e77f57795e660d06f578c9614 Mon Sep 17 00:00:00 2001 From: Fazlay Rabbi Date: Thu, 17 Nov 2022 16:20:14 -0800 Subject: [PATCH] [OpenMP] Initial parsing/sema for 'strict' modifier with 'grainsize' clause This patch gives basic parsing and semantic analysis support for 'strict' modifier with 'grainsize' clause of 'taskloop' construct introduced in OpenMP 5.1 (section 2.12.2) Differential Revision: https://reviews.llvm.org/D138217 --- clang/include/clang/AST/OpenMPClause.h | 31 ++++- clang/include/clang/Basic/DiagnosticParseKinds.td | 1 + clang/include/clang/Basic/OpenMPKinds.def | 7 + clang/include/clang/Basic/OpenMPKinds.h | 6 + clang/include/clang/Sema/Sema.h | 4 +- clang/lib/AST/OpenMPClause.cpp | 5 + clang/lib/Basic/OpenMPKinds.cpp | 21 ++- clang/lib/Parse/ParseOpenMP.cpp | 32 ++++- clang/lib/Sema/SemaOpenMP.cpp | 45 +++++-- clang/lib/Sema/TreeTransform.h | 11 +- clang/lib/Serialization/ASTReader.cpp | 2 + clang/lib/Serialization/ASTWriter.cpp | 2 + .../OpenMP/masked_taskloop_grainsize_messages.cpp | 2 + .../masked_taskloop_simd_grainsize_messages.cpp | 2 + .../OpenMP/master_taskloop_grainsize_messages.cpp | 2 + .../master_taskloop_simd_grainsize_messages.cpp | 2 + ...lel_masked_taskloop_simd_grainsize_messages.cpp | 2 + ...parallel_master_taskloop_grainsize_messages.cpp | 2 + ...lel_master_taskloop_simd_grainsize_messages.cpp | 2 + clang/test/OpenMP/taskloop_grainsize_messages.cpp | 2 + .../OpenMP/taskloop_simd_grainsize_messages.cpp | 2 + .../OpenMP/taskloop_strict_modifier_ast_print.cpp | 142 +++++++++++++++++++++ .../OpenMP/taskloop_strict_modifier_messages.cpp | 113 ++++++++++++++++ llvm/include/llvm/Frontend/OpenMP/OMP.td | 9 ++ 24 files changed, 423 insertions(+), 26 deletions(-) create mode 100644 clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp create mode 100644 clang/test/OpenMP/taskloop_strict_modifier_messages.cpp diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index e7dc5e7..1c9f623 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -6354,26 +6354,43 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { /// 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); } @@ -6392,6 +6409,12 @@ public: /// 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 { diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 27cd3da..6f46ede 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1316,6 +1316,7 @@ def warn_pragma_unsupported_extension : Warning< 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< diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 0f023b3..339139a 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -71,6 +71,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) @@ -181,6 +184,10 @@ OPENMP_BIND_KIND(teams) 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 diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 4a8417c..da13756 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -195,6 +195,12 @@ enum OpenMPBindClauseKind { 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 { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4696403..4628ffe 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11679,8 +11679,10 @@ public: 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, diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index eb4e797..07022a7 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1920,6 +1920,11 @@ void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) { 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 << ")"; } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index bb1c231..2a46b46 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -149,6 +149,15 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, #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: @@ -188,7 +197,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: - case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: case OMPC_hint: @@ -436,6 +444,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #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: @@ -475,7 +493,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: - case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: case OMPC_hint: diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index e306e62..d699854 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -3226,6 +3226,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, 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; @@ -3871,6 +3873,33 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, Arg.push_back(OMPC_DEVICE_unknown); KLoc.emplace_back(); } + } else if (Kind == OMPC_grainsize) { + // Parse optional ':' + OpenMPGrainsizeClauseModifier Modifier = + static_cast(getOpenMPSimpleClauseType( + Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), + getLangOpts())); + if (getLangOpts().OpenMP >= 51) { + if (NextToken().is(tok::colon)) { + Arg.push_back(Modifier); + KLoc.push_back(Tok.getLocation()); + // Parse modifier + ConsumeAnyToken(); + // Parse ':' + ConsumeAnyToken(); + } else { + if (Modifier == OMPC_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()); @@ -3893,7 +3922,8 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, 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)); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7df2750..edeca63 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -15110,9 +15110,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 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; @@ -15140,6 +15137,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_align: Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); break; + case OMPC_grainsize: case OMPC_device: case OMPC_if: case OMPC_default: @@ -16879,6 +16877,13 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 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: @@ -16924,7 +16929,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_num_teams: case OMPC_thread_limit: case OMPC_priority: - case OMPC_grainsize: case OMPC_nogroup: case OMPC_num_tasks: case OMPC_hint: @@ -22352,10 +22356,21 @@ OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 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; @@ -22363,14 +22378,16 @@ OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, // 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, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 7c85a8cbc..ee63328 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2051,11 +2051,13 @@ public: /// /// 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. @@ -10350,7 +10352,8 @@ TreeTransform::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) { 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 diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 5e853fb..83e539d 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -10784,7 +10784,9 @@ void OMPClauseReader::VisitOMPPriorityClause(OMPPriorityClause *C) { void OMPClauseReader::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { VisitOMPClauseWithPreInit(C); + C->setModifier(Record.readEnum()); C->setGrainsize(Record.readSubExpr()); + C->setModifierLoc(Record.readSourceLocation()); C->setLParenLoc(Record.readSourceLocation()); } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e944d2e..2567cb3 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6790,7 +6790,9 @@ void OMPClauseWriter::VisitOMPPriorityClause(OMPPriorityClause *C) { void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) { VisitOMPClauseWithPreInit(C); + Record.writeEnum(C->getModifier()); Record.AddStmt(C->getGrainsize()); + Record.AddSourceLocation(C->getModifierLoc()); Record.AddSourceLocation(C->getLParenLoc()); } diff --git a/clang/test/OpenMP/masked_taskloop_grainsize_messages.cpp b/clang/test/OpenMP/masked_taskloop_grainsize_messages.cpp index 636db37..518d130 100644 --- a/clang/test/OpenMP/masked_taskloop_grainsize_messages.cpp +++ b/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() { } diff --git a/clang/test/OpenMP/masked_taskloop_simd_grainsize_messages.cpp b/clang/test/OpenMP/masked_taskloop_simd_grainsize_messages.cpp index 0a6a3b4..10b40b6 100644 --- a/clang/test/OpenMP/masked_taskloop_simd_grainsize_messages.cpp +++ b/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() { } diff --git a/clang/test/OpenMP/master_taskloop_grainsize_messages.cpp b/clang/test/OpenMP/master_taskloop_grainsize_messages.cpp index 077dfb9..dbc72b6 100644 --- a/clang/test/OpenMP/master_taskloop_grainsize_messages.cpp +++ b/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() { } diff --git a/clang/test/OpenMP/master_taskloop_simd_grainsize_messages.cpp b/clang/test/OpenMP/master_taskloop_simd_grainsize_messages.cpp index f258ee8..6670be9 100644 --- a/clang/test/OpenMP/master_taskloop_simd_grainsize_messages.cpp +++ b/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() { } diff --git a/clang/test/OpenMP/parallel_masked_taskloop_simd_grainsize_messages.cpp b/clang/test/OpenMP/parallel_masked_taskloop_simd_grainsize_messages.cpp index 68661dc..ad9c5b6 100644 --- a/clang/test/OpenMP/parallel_masked_taskloop_simd_grainsize_messages.cpp +++ b/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() { } diff --git a/clang/test/OpenMP/parallel_master_taskloop_grainsize_messages.cpp b/clang/test/OpenMP/parallel_master_taskloop_grainsize_messages.cpp index 676ce86..a79deb4 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_grainsize_messages.cpp +++ b/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() { } diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_grainsize_messages.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_grainsize_messages.cpp index 318d5b7..93e2936 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_simd_grainsize_messages.cpp +++ b/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() { } diff --git a/clang/test/OpenMP/taskloop_grainsize_messages.cpp b/clang/test/OpenMP/taskloop_grainsize_messages.cpp index 174d910..f5f4312 100644 --- a/clang/test/OpenMP/taskloop_grainsize_messages.cpp +++ b/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() { } diff --git a/clang/test/OpenMP/taskloop_simd_grainsize_messages.cpp b/clang/test/OpenMP/taskloop_simd_grainsize_messages.cpp index 4c4bf39..468ab59 100644 --- a/clang/test/OpenMP/taskloop_simd_grainsize_messages.cpp +++ b/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() { } diff --git a/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp b/clang/test/OpenMP/taskloop_strict_modifier_ast_print.cpp new file mode 100644 index 0000000..3f2494e --- /dev/null +++ b/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 diff --git a/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp b/clang/test/OpenMP/taskloop_strict_modifier_messages.cpp new file mode 100644 index 0000000..e9024a0 --- /dev/null +++ b/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); +} diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index 0e76fc1..18a98ba 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -230,9 +230,18 @@ def OMPC_Priority : Clause<"priority"> { let clangClass = "OMPPriorityClause"; let flangClass = "ScalarIntExpr"; } + +def OMP_GRAINSIZE_Strict : ClauseVal<"strict", 1, 1> {} +def OMP_GRAINSIZE_Unknown : ClauseVal<"unkonwn", 2, 0> { let isDefault = 1; } + def OMPC_GrainSize : Clause<"grainsize"> { let clangClass = "OMPGrainsizeClause"; let flangClass = "ScalarIntExpr"; + let enumClauseValue = "GrainsizeType"; + let allowedClauseValues = [ + OMP_GRAINSIZE_Strict, + OMP_GRAINSIZE_Unknown + ]; } def OMPC_NoGroup : Clause<"nogroup"> { let clangClass = "OMPNogroupClause"; -- 2.7.4