https://github.com/mdfazlay updated https://github.com/llvm/llvm-project/pull/159628
>From f38bd6e830aa898d008eb267742861ca096a647e Mon Sep 17 00:00:00 2001 From: Fazlay Rabbi <fazlay.ra...@intel.com> Date: Thu, 18 Sep 2025 11:53:59 -0700 Subject: [PATCH 1/2] [OpenMP 60] Update parsing and semantic support for `nowait` clause to accept optional argument This PR enhances the OpenMP `nowait` clause implementation by adding support for optional argument in both parsing and semantic analysis phases. Reference: 1. OpenMP 6.0 Specification, page 481 --- clang/include/clang/AST/OpenMPClause.h | 58 ++++++++++++++++--- clang/include/clang/AST/RecursiveASTVisitor.h | 3 +- clang/include/clang/Sema/SemaOpenMP.h | 6 +- clang/lib/AST/OpenMPClause.cpp | 14 ++++- clang/lib/AST/StmtProfile.cpp | 5 +- clang/lib/Parse/ParseOpenMP.cpp | 5 +- clang/lib/Sema/SemaOpenMP.cpp | 25 +++++++- clang/lib/Sema/TreeTransform.h | 21 ++++++- clang/lib/Serialization/ASTReader.cpp | 5 +- clang/lib/Serialization/ASTWriter.cpp | 5 +- clang/test/OpenMP/nowait_ast_print.cpp | 56 ++++++++++++++++++ .../target_enter_data_nowait_messages.cpp | 14 ++++- .../target_exit_data_nowait_messages.cpp | 10 +++- clang/test/OpenMP/target_nowait_messages.cpp | 13 ++++- .../target_parallel_for_nowait_messages.cpp | 14 ++++- ...rget_parallel_for_simd_nowait_messages.cpp | 14 ++++- .../target_parallel_nowait_messages.cpp | 15 ++++- .../OpenMP/target_simd_nowait_messages.cpp | 14 ++++- ...arget_teams_distribute_nowait_messages.cpp | 7 +-- ...istribute_parallel_for_nowait_messages.cpp | 14 ++++- ...bute_parallel_for_simd_nowait_messages.cpp | 14 ++++- ..._teams_distribute_simd_nowait_messages.cpp | 14 ++++- .../OpenMP/target_teams_nowait_messages.cpp | 15 +++-- .../OpenMP/target_update_nowait_messages.cpp | 12 ++-- clang/tools/libclang/CIndex.cpp | 4 +- llvm/include/llvm/Frontend/OpenMP/OMP.td | 2 + 26 files changed, 316 insertions(+), 63 deletions(-) create mode 100644 clang/test/OpenMP/nowait_ast_print.cpp diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index b2a6d4b9182b0..fd90988971d8d 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -2217,18 +2217,62 @@ class OMPOrderedClause final /// This represents 'nowait' clause in the '#pragma omp ...' directive. /// /// \code -/// #pragma omp for nowait +/// #pragma omp for nowait (cond) /// \endcode -/// In this example directive '#pragma omp for' has 'nowait' clause. -class OMPNowaitClause final : public OMPNoChildClause<llvm::omp::OMPC_nowait> { +/// In this example directive '#pragma omp for' has simple 'nowait' clause with +/// condition 'cond'. +class OMPNowaitClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// Condition of the 'nowait' clause. + Stmt *Condition = nullptr; + + /// Set condition. + void setCondition(Expr *Cond) { Condition = Cond; } + public: - /// Build 'nowait' clause. + /// Build 'nowait' clause with condition \a Cond. /// + /// \param Cond Condition of the clause. /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - OMPNowaitClause(SourceLocation StartLoc = SourceLocation(), - SourceLocation EndLoc = SourceLocation()) - : OMPNoChildClause(StartLoc, EndLoc) {} + OMPNowaitClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc), + LParenLoc(LParenLoc), Condition(Cond) {} + + /// Build an empty clause. + OMPNowaitClause() + : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {} + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns condition. + Expr *getCondition() const { return cast_or_null<Expr>(Condition); } + + child_range children() { return child_range(&Condition, &Condition + 1); } + + const_child_range children() const { + return const_child_range(&Condition, &Condition + 1); + } + + child_range used_children(); + const_child_range used_children() const { + auto Children = const_cast<OMPNowaitClause *>(this)->used_children(); + return const_child_range(Children.begin(), Children.end()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_nowait; + } }; /// This represents 'untied' clause in the '#pragma omp ...' directive. diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index c1944487716de..8f1500993dcc8 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3576,7 +3576,8 @@ bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *C) { } template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) { +bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *C) { + TRY_TO(TraverseStmt(C->getCondition())); return true; } diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 23827051ed724..511aab39ec93d 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1002,8 +1002,10 @@ class SemaOpenMP : public SemaBase { OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc); /// Called on well-formed 'nowait' clause. - OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc, - SourceLocation EndLoc); + OMPClause * + ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc, + SourceLocation LParenLoc = SourceLocation(), + Expr *Condition = nullptr); /// Called on well-formed 'untied' clause. OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc); diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 69d33019c0952..c7876cc9cd1db 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -306,6 +306,13 @@ OMPClause::child_range OMPIfClause::used_children() { return child_range(&Condition, &Condition + 1); } +OMPClause::child_range OMPNowaitClause::used_children() { + if (Condition) + return child_range(&Condition, &Condition + 1); + Stmt *Null = nullptr; + return child_range(&Null, &Null); +} + OMPClause::child_range OMPGrainsizeClause::used_children() { if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt())) return child_range(C, C + 1); @@ -2004,8 +2011,13 @@ void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) { } } -void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) { +void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *Node) { OS << "nowait"; + if (auto *Cond = Node->getCondition()) { + OS << "("; + Cond->printPretty(OS, nullptr, Policy, 0); + OS << ")"; + } } void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 37c4d43ec0b2f..65a03cd7f91b3 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -578,7 +578,10 @@ void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *C) { Profiler->VisitStmt(Num); } -void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {} +void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *C) { + if (C->getCondition()) + Profiler->VisitStmt(C->getCondition()); +} void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {} diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 7dceb2d208352..c17f499a7710f 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -3025,6 +3025,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_simdlen: case OMPC_collapse: case OMPC_ordered: + case OMPC_nowait: case OMPC_priority: case OMPC_grainsize: case OMPC_num_tasks: @@ -3073,7 +3074,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, ErrorFound = true; } - if ((CKind == OMPC_ordered || CKind == OMPC_partial) && + if ((CKind == OMPC_ordered || CKind == OMPC_nowait || + CKind == OMPC_partial) && PP.LookAhead(/*N=*/0).isNot(tok::l_paren)) Clause = ParseOpenMPClause(CKind, WrongDirective); else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks || @@ -3138,7 +3140,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_holds: Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective); break; - case OMPC_nowait: case OMPC_untied: case OMPC_mergeable: case OMPC_read: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 6a7a5a9a4303a..b14bbfc163e9c 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -15646,6 +15646,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, case OMPC_ordered: Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); break; + case OMPC_nowait: + Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc, LParenLoc, Expr); + break; case OMPC_priority: Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); break; @@ -15701,7 +15704,6 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, case OMPC_aligned: case OMPC_copyin: case OMPC_copyprivate: - case OMPC_nowait: case OMPC_untied: case OMPC_mergeable: case OMPC_threadprivate: @@ -17233,9 +17235,26 @@ OMPClause *SemaOpenMP::ActOnOpenMPClause(OpenMPClauseKind Kind, } OMPClause *SemaOpenMP::ActOnOpenMPNowaitClause(SourceLocation StartLoc, - SourceLocation EndLoc) { + SourceLocation EndLoc, + SourceLocation LParenLoc, + Expr *Condition) { + Expr *ValExpr = Condition; + if (Condition && LParenLoc.isValid()) { + if (!Condition->isValueDependent() && !Condition->isTypeDependent() && + !Condition->isInstantiationDependent() && + !Condition->containsUnexpandedParameterPack()) { + ExprResult Val = SemaRef.CheckBooleanCondition(StartLoc, Condition); + if (Val.isInvalid()) + return nullptr; + + ValExpr = Val.get(); + } + } else { + ValExpr = nullptr; + } DSAStack->setNowaitRegion(); - return new (getASTContext()) OMPNowaitClause(StartLoc, EndLoc); + return new (getASTContext()) + OMPNowaitClause(ValExpr, StartLoc, LParenLoc, EndLoc); } OMPClause *SemaOpenMP::ActOnOpenMPUntiedClause(SourceLocation StartLoc, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 242ffb09af006..a748219051304 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1857,6 +1857,17 @@ class TreeTransform { LParenLoc, Num); } + /// Build a new OpenMP 'nowait' clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc, + LParenLoc, Condition); + } + /// Build a new OpenMP 'private' clause. /// /// By default, performs semantic analysis to build the new OpenMP clause. @@ -10569,8 +10580,14 @@ TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) { template <typename Derived> OMPClause * TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; + ExprResult Cond; + if (auto *Condition = C->getCondition()) { + Cond = getDerived().TransformExpr(Condition); + if (Cond.isInvalid()) + return nullptr; + } + return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(), + C->getLParenLoc(), C->getEndLoc()); } template <typename Derived> diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 9ee8a0fb0f060..8f9fda88bd661 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11673,7 +11673,10 @@ void OMPClauseReader::VisitOMPDetachClause(OMPDetachClause *C) { C->setLParenLoc(Record.readSourceLocation()); } -void OMPClauseReader::VisitOMPNowaitClause(OMPNowaitClause *) {} +void OMPClauseReader::VisitOMPNowaitClause(OMPNowaitClause *C) { + C->setCondition(Record.readSubExpr()); + C->setLParenLoc(Record.readSourceLocation()); +} void OMPClauseReader::VisitOMPUntiedClause(OMPUntiedClause *) {} diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 3293a54a0a093..fac91d86858e7 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -7926,7 +7926,10 @@ void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *C) { Record.AddSourceLocation(C->getLParenLoc()); } -void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *) {} +void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *C) { + Record.AddStmt(C->getCondition()); + Record.AddSourceLocation(C->getLParenLoc()); +} void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {} diff --git a/clang/test/OpenMP/nowait_ast_print.cpp b/clang/test/OpenMP/nowait_ast_print.cpp new file mode 100644 index 0000000000000..4151a397beb9c --- /dev/null +++ b/clang/test/OpenMP/nowait_ast_print.cpp @@ -0,0 +1,56 @@ +// Check no warnings/errors +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -fsyntax-only -verify %s +// expected-no-diagnostics + +// Check AST and unparsing +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -ast-dump %s | FileCheck %s --check-prefix=DUMP +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -ast-print %s | FileCheck %s --check-prefix=PRINT + +// Check same results after serialization round-trip +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -emit-pch -o %t %s +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT + +#ifndef HEADER +#define HEADER + +void nowait() { + int A=1; + + // DUMP: OMPTargetDirective + // DUMP-NEXT: OMPNowaitClause + // DUMP-NEXT: <<<NULL>>> + // PRINT: #pragma omp target nowait + #pragma omp target nowait + { + } + + // DUMP: OMPTargetDirective + // DUMP-NEXT: OMPNowaitClause + // DUMP-NEXT: XXBoolLiteralExpr {{.*}} 'bool' false + // PRINT: #pragma omp target nowait(false) + #pragma omp target nowait(false) + { + } + + // DUMP: OMPTargetDirective + // DUMP-NEXT: OMPNowaitClause + // DUMP-NEXT: XXBoolLiteralExpr {{.*}} 'bool' true + // PRINT: #pragma omp target nowait(true) + #pragma omp target nowait(true) + { + } + + // DUMP: OMPTargetDirective + // DUMP-NEXT: OMPNowaitClause + // DUMP-NEXT: BinaryOperator {{.*}} 'bool' '>' + // DUMP-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> + // DUMP-NEXT: DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'A' 'int' + // DUMP-NEXT: IntegerLiteral {{.*}} 'int' 5 + // PRINT: #pragma omp target nowait(A > 5) + #pragma omp target nowait(A>5) + { + } + +} +#endif \ No newline at end of file diff --git a/clang/test/OpenMP/target_enter_data_nowait_messages.cpp b/clang/test/OpenMP/target_enter_data_nowait_messages.cpp index ba5eaf1d2214a..0b892325a1c69 100644 --- a/clang/test/OpenMP/target_enter_data_nowait_messages.cpp +++ b/clang/test/OpenMP/target_enter_data_nowait_messages.cpp @@ -13,15 +13,23 @@ int main(int argc, char **argv) { {} #pragma omp target enter nowait data map(to: i) // expected-error {{expected an OpenMP directive}} {} - #pragma omp target enter data nowait() map(to: i) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} expected-error {{expected at least one 'map' clause for '#pragma omp target enter data'}} + #pragma omp target enter data nowait() map(to: i) // expected-error {{expected expression}} {} - #pragma omp target enter data map(to: i) nowait( // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} + #pragma omp target enter data map(to: i) nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} {} #pragma omp target enter data map(to: i) nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} {} #pragma omp target enter data map(to: i) nowait device (-10u) {} - #pragma omp target enter data map(to: i) nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} + #pragma omp target enter data map(to: i) nowait (3.14) device (-10u) + {} + #pragma omp target enter data map(to: i) nowait (argc>> i) + {} + #pragma omp target enter data map(to: i) nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + {} + #pragma omp target enter data map(to: i) nowait (argc > 0 ? argv[1] : argv[2]) + {} + #pragma omp target enter data map(to: i) nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} {} #pragma omp target enter data map(to: i) nowait nowait // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'nowait' clause}} {} diff --git a/clang/test/OpenMP/target_exit_data_nowait_messages.cpp b/clang/test/OpenMP/target_exit_data_nowait_messages.cpp index 307e2c34b27fb..a248704a49e9e 100644 --- a/clang/test/OpenMP/target_exit_data_nowait_messages.cpp +++ b/clang/test/OpenMP/target_exit_data_nowait_messages.cpp @@ -8,11 +8,15 @@ int main(int argc, char **argv) { #pragma omp nowait target exit data map(from: i) // expected-error {{expected an OpenMP directive}} #pragma omp target nowait exit data map(from: i) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} #pragma omp target exit nowait data map(from: i) // expected-error {{expected an OpenMP directive}} - #pragma omp target exit data nowait() map(from: i) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} expected-error {{expected at least one 'map' clause for '#pragma omp target exit data'}} - #pragma omp target exit data map(from: i) nowait( // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} + #pragma omp target exit data nowait() map(from: i) // expected-error {{expected expression}} + #pragma omp target exit data map(from: i) nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} #pragma omp target exit data map(from: i) nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} #pragma omp target exit data map(from: i) nowait device (-10u) - #pragma omp target exit data map(from: i) nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} + #pragma omp target exit data map(from: i) nowait (3.14) device (-10u) + #pragma omp target exit data map(from: i) nowait (argc>> i) + #pragma omp target exit data map(from: i) nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target exit data map(from: i) nowait (argc > 0 ? argv[1] : argv[2]) + #pragma omp target exit data map(from: i) nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} #pragma omp target exit data map(from: i) nowait nowait // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'nowait' clause}} #pragma omp target exit data nowait map(from: i) nowait // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'nowait' clause}} return 0; diff --git a/clang/test/OpenMP/target_nowait_messages.cpp b/clang/test/OpenMP/target_nowait_messages.cpp index 6b8a1f4d0ac47..6c2d85529eb71 100644 --- a/clang/test/OpenMP/target_nowait_messages.cpp +++ b/clang/test/OpenMP/target_nowait_messages.cpp @@ -6,13 +6,22 @@ void foo() { } int main(int argc, char **argv) { - #pragma omp target nowait( // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + int i; + #pragma omp target nowait(// expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} foo(); #pragma omp target nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} foo(); #pragma omp target nowait device (-10u) foo(); - #pragma omp target nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + #pragma omp target nowait (3.14) device (-10u) + foo(); + #pragma omp target nowait (argc>> i) + foo(); + #pragma omp target nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target nowait (argc > 0 ? argv[1] : argv[2]) + foo(); + #pragma omp target nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} foo(); return 0; diff --git a/clang/test/OpenMP/target_parallel_for_nowait_messages.cpp b/clang/test/OpenMP/target_parallel_for_nowait_messages.cpp index 2f88c6581d4f2..6059c6433da4f 100644 --- a/clang/test/OpenMP/target_parallel_for_nowait_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_nowait_messages.cpp @@ -6,14 +6,22 @@ void foo() { } int main(int argc, char **argv) { - int i; - #pragma omp target parallel for nowait( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + int i, z; + #pragma omp target parallel for nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for nowait device (-10u) for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + #pragma omp target parallel for nowait (3.14) device (-10u) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for nowait (argc>> z) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for nowait (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} for (i = 0; i < argc; ++i) foo(); return 0; diff --git a/clang/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp index 4220bfea3ee3f..ee72b750d5307 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp @@ -6,14 +6,22 @@ void foo() { } int main(int argc, char **argv) { - int i; - #pragma omp target parallel for simd nowait( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + int i, z; + #pragma omp target parallel for simd nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd nowait device (-10u) for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + #pragma omp target parallel for simd nowait (3.14) device (-10u) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd nowait (argc>> z) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd nowait (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} for (i = 0; i < argc; ++i) foo(); return 0; diff --git a/clang/test/OpenMP/target_parallel_nowait_messages.cpp b/clang/test/OpenMP/target_parallel_nowait_messages.cpp index 3e285fca3aee1..0d7a823dd7a38 100644 --- a/clang/test/OpenMP/target_parallel_nowait_messages.cpp +++ b/clang/test/OpenMP/target_parallel_nowait_messages.cpp @@ -6,13 +6,22 @@ void foo() { } int main(int argc, char **argv) { - #pragma omp target parallel nowait( // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} - foo(); + int z; + #pragma omp target parallel nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} + foo(); #pragma omp target parallel nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} foo(); #pragma omp target parallel nowait device (-10u) foo(); - #pragma omp target parallel nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + #pragma omp target parallel nowait (3.14) device (-10u) + foo(); + #pragma omp target parallel nowait (argc>> z) + foo(); + #pragma omp target parallel nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel nowait (argc > 0 ? argv[1] : argv[2]) + foo(); + #pragma omp target parallel nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} foo(); return 0; diff --git a/clang/test/OpenMP/target_simd_nowait_messages.cpp b/clang/test/OpenMP/target_simd_nowait_messages.cpp index 1aee110969489..2c874d9e92e88 100644 --- a/clang/test/OpenMP/target_simd_nowait_messages.cpp +++ b/clang/test/OpenMP/target_simd_nowait_messages.cpp @@ -6,14 +6,22 @@ void foo() { } int main(int argc, char **argv) { - int i; - #pragma omp target simd nowait( // expected-warning {{extra tokens at the end of '#pragma omp target simd' are ignored}} + int i, z; + #pragma omp target simd nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target simd' are ignored}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd nowait device (-10u) for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target simd' are ignored}} + #pragma omp target simd nowait (3.14) device (-10u) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target simd nowait (argc>> z) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target simd nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target simd nowait (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target simd nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} for (i = 0; i < argc; ++i) foo(); return 0; diff --git a/clang/test/OpenMP/target_teams_distribute_nowait_messages.cpp b/clang/test/OpenMP/target_teams_distribute_nowait_messages.cpp index 75bab8001bfb7..5bc1ed359ed58 100644 --- a/clang/test/OpenMP/target_teams_distribute_nowait_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_nowait_messages.cpp @@ -7,13 +7,12 @@ void foo() { int main(int argc, char **argv) { int i; -#pragma omp target teams distribute nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}} +#pragma omp target teams distribute nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} +#pragma omp target teams distribute nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}} //expected-error {{region cannot be nested inside 'target teams distribute' region}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute nowait device (-10u) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}} +#pragma omp target teams distribute nowait (3.14) device (-10u) // expected-error {{arguments of OpenMP clause 'nowait' with bitwise operators cannot be of floating type}} for (i = 0; i < argc; ++i) foo(); return 0; diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_nowait_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_nowait_messages.cpp index f6b6061dd42b7..afb49e7101d1d 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_nowait_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_nowait_messages.cpp @@ -6,14 +6,22 @@ void foo() { } int main(int argc, char **argv) { - int i; -#pragma omp target teams distribute parallel for nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}} + int i, z; +#pragma omp target teams distribute parallel for nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for nowait device (-10u) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}} +#pragma omp target teams distribute parallel for nowait (3.14) device (-10u) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for nowait (argc>> z) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for nowait (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} for (i = 0; i < argc; ++i) foo(); return 0; diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_nowait_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_nowait_messages.cpp index 0f13d35c06717..0fb7dc6304d0e 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_nowait_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_nowait_messages.cpp @@ -6,14 +6,22 @@ void foo() { } int main(int argc, char **argv) { - int i; -#pragma omp target teams distribute parallel for simd nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}} + int i, z; +#pragma omp target teams distribute parallel for simd nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd nowait device (-10u) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}} +#pragma omp target teams distribute parallel for simd nowait (3.14) device (-10u) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for simd nowait (argc>> z) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for simd nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for simd nowait (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for simd nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} for (i = 0; i < argc; ++i) foo(); return 0; diff --git a/clang/test/OpenMP/target_teams_distribute_simd_nowait_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_nowait_messages.cpp index 1a9d0b5a51625..3108c7ebc621a 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_nowait_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_nowait_messages.cpp @@ -6,14 +6,22 @@ void foo() { } int main(int argc, char **argv) { - int i; -#pragma omp target teams distribute simd nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}} + int i, z; +#pragma omp target teams distribute simd nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd nowait device (-10u) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}} +#pragma omp target teams distribute simd nowait (3.14) device (-10u) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute simd nowait (argc>> z) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute simd nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute simd nowait (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute simd nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} for (i = 0; i < argc; ++i) foo(); return 0; diff --git a/clang/test/OpenMP/target_teams_nowait_messages.cpp b/clang/test/OpenMP/target_teams_nowait_messages.cpp index bed2f979891e9..1d5d065423ad8 100644 --- a/clang/test/OpenMP/target_teams_nowait_messages.cpp +++ b/clang/test/OpenMP/target_teams_nowait_messages.cpp @@ -6,13 +6,20 @@ void foo() { } int main(int argc, char **argv) { -#pragma omp target teams nowait( // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}} - foo(); -#pragma omp target teams nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}} + int z; +#pragma omp target teams nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} //expected-note {{to match this '('}} foo(); #pragma omp target teams nowait device (-10u) foo(); -#pragma omp target teams nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}} +#pragma omp target teams nowait (3.14) device (-10u) + foo(); +#pragma omp target teams nowait (argc>> z) + foo(); +#pragma omp target teams nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target teams nowait (argc > 0 ? argv[1] : argv[2]) + foo(); +#pragma omp target teams nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} foo(); return 0; diff --git a/clang/test/OpenMP/target_update_nowait_messages.cpp b/clang/test/OpenMP/target_update_nowait_messages.cpp index fc0314a31874f..a53dab7bb7fd8 100644 --- a/clang/test/OpenMP/target_update_nowait_messages.cpp +++ b/clang/test/OpenMP/target_update_nowait_messages.cpp @@ -3,17 +3,21 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized int main(int argc, char **argv) { - int i; + int i, z; #pragma omp nowait target update to(i) // expected-error {{expected an OpenMP directive}} #pragma omp target nowait update to(i) // expected-error {{unexpected OpenMP clause 'update' in directive '#pragma omp target'}} expected-error {{unexpected OpenMP clause 'to' in directive '#pragma omp target'}} {} - #pragma omp target update nowait() to(i) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} - #pragma omp target update to(i) nowait( // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update nowait() to(i) // expected-error {{expected expression}} + #pragma omp target update to(i) nowait( // expected-error {{expected expression}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} #pragma omp target update to(i) nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} #pragma omp target update to(i) nowait device (-10u) - #pragma omp target update to(i) nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(i) nowait (3.14) device (-10u) #pragma omp target update to(i) nowait nowait // expected-error {{directive '#pragma omp target update' cannot contain more than one 'nowait' clause}} #pragma omp target update nowait to(i) nowait // expected-error {{directive '#pragma omp target update' cannot contain more than one 'nowait' clause}} + #pragma omp target update to(i) nowait (argc>> z) + #pragma omp target update to(i) nowait (argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target update to(i) nowait (argc > 0 ? argv[1] : argv[2]) + #pragma omp target update to(i) nowait (S1) // expected-error {{use of undeclared identifier 'S1'}} return 0; } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 9526f629bda42..f29eaa848e0a1 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2378,7 +2378,9 @@ void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) { Visitor->AddStmt(C->getEventHandler()); } -void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {} +void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *C) { + Visitor->AddStmt(C->getCondition()); +} void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {} diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index 6a41c24e78149..6b134ab1c4ceb 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -349,6 +349,7 @@ def OMPC_Novariants : Clause<[Spelling<"novariants">]> { } def OMPC_NoWait : Clause<[Spelling<"nowait">]> { let clangClass = "OMPNowaitClause"; + let isValueOptional = true; } def OMP_NUMTASKS_Strict : EnumVal<"strict", 1, 1> {} def OMP_NUMTASKS_Unknown : EnumVal<"unknown", 2, 0> { let isDefault = 1; } @@ -704,6 +705,7 @@ def OMP_Cancel : Directive<[Spelling<"cancel">]> { let allowedOnceClauses = [ VersionedClause<OMPC_CancellationConstructType>, VersionedClause<OMPC_If>, + VersionedClause<OMPC_NoWait, 60>, ]; let association = AS_None; let category = CA_Executable; >From 9094605236cfdbbfb171306165b8c3ade0951ae9 Mon Sep 17 00:00:00 2001 From: Fazlay Rabbi <fazlay.ra...@intel.com> Date: Thu, 18 Sep 2025 12:15:49 -0700 Subject: [PATCH 2/2] Minor LIT test fix --- clang/test/OpenMP/nowait_ast_print.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/OpenMP/nowait_ast_print.cpp b/clang/test/OpenMP/nowait_ast_print.cpp index 4151a397beb9c..b728029543e1c 100644 --- a/clang/test/OpenMP/nowait_ast_print.cpp +++ b/clang/test/OpenMP/nowait_ast_print.cpp @@ -53,4 +53,4 @@ void nowait() { } } -#endif \ No newline at end of file +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits