Skip to content

Commit f9910a2

Browse files
authored
[OpenMP 60] Update parsing and semantic support for nowait clause to accept optional argument (#159628)
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
1 parent bf6880c commit f9910a2

28 files changed

+436
-97
lines changed

clang/docs/OpenMPSupport.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ implementation.
505505
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
506506
| pure directives in DO CONCURRENT | | :none:`unclaimed` | |
507507
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
508-
| Optional argument for all clauses | :none:`unclaimed` | :none:`unclaimed` | |
508+
| Optional argument for all clauses | :none:`partial` | :none:`In Progress` | Parse/Sema (nowait): https://github.com/llvm/llvm-project/pull/159628 |
509509
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
510510
| Function references for locator list items | :none:`unclaimed` | :none:`unclaimed` | |
511511
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,8 @@ OpenMP Support
641641
- Added support for ``defaultmap`` directive implicit-behavior ``private``.
642642
- Added parsing and semantic analysis support for ``groupprivate`` directive.
643643
- Added support for 'omp fuse' directive.
644+
- Updated parsing and semantic analysis support for ``nowait`` clause to accept
645+
optional argument in OpenMP >= 60.
644646

645647
Improvements
646648
^^^^^^^^^^^^

clang/include/clang/AST/OpenMPClause.h

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,18 +2291,68 @@ class OMPOrderedClause final
22912291
/// This represents 'nowait' clause in the '#pragma omp ...' directive.
22922292
///
22932293
/// \code
2294-
/// #pragma omp for nowait
2294+
/// #pragma omp for nowait (cond)
22952295
/// \endcode
2296-
/// In this example directive '#pragma omp for' has 'nowait' clause.
2297-
class OMPNowaitClause final : public OMPNoChildClause<llvm::omp::OMPC_nowait> {
2296+
/// In this example directive '#pragma omp for' has simple 'nowait' clause with
2297+
/// condition 'cond'.
2298+
class OMPNowaitClause final : public OMPClause {
2299+
friend class OMPClauseReader;
2300+
2301+
/// Location of '('.
2302+
SourceLocation LParenLoc;
2303+
2304+
/// Condition of the 'nowait' clause.
2305+
Stmt *Condition = nullptr;
2306+
2307+
/// Set condition.
2308+
void setCondition(Expr *Cond) { Condition = Cond; }
2309+
22982310
public:
2299-
/// Build 'nowait' clause.
2311+
/// Build 'nowait' clause with condition \a Cond.
23002312
///
2313+
/// \param Cond Condition of the clause.
23012314
/// \param StartLoc Starting location of the clause.
2315+
/// \param LParenLoc Location of '('.
23022316
/// \param EndLoc Ending location of the clause.
2303-
OMPNowaitClause(SourceLocation StartLoc = SourceLocation(),
2304-
SourceLocation EndLoc = SourceLocation())
2305-
: OMPNoChildClause(StartLoc, EndLoc) {}
2317+
OMPNowaitClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
2318+
SourceLocation EndLoc)
2319+
: OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc),
2320+
LParenLoc(LParenLoc), Condition(Cond) {}
2321+
2322+
/// Build an empty clause.
2323+
OMPNowaitClause()
2324+
: OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {}
2325+
2326+
/// Sets the location of '('.
2327+
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
2328+
2329+
/// Returns the location of '('.
2330+
SourceLocation getLParenLoc() const { return LParenLoc; }
2331+
2332+
/// Returns condition.
2333+
Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
2334+
2335+
child_range children() {
2336+
if (Condition)
2337+
return child_range(&Condition, &Condition + 1);
2338+
return child_range(child_iterator(), child_iterator());
2339+
}
2340+
2341+
const_child_range children() const {
2342+
if (Condition)
2343+
return const_child_range(&Condition, &Condition + 1);
2344+
return const_child_range(const_child_iterator(), const_child_iterator());
2345+
}
2346+
2347+
child_range used_children();
2348+
const_child_range used_children() const {
2349+
auto Children = const_cast<OMPNowaitClause *>(this)->used_children();
2350+
return const_child_range(Children.begin(), Children.end());
2351+
}
2352+
2353+
static bool classof(const OMPClause *T) {
2354+
return T->getClauseKind() == llvm::omp::OMPC_nowait;
2355+
}
23062356
};
23072357

23082358
/// This represents 'untied' clause in the '#pragma omp ...' directive.

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3594,7 +3594,8 @@ bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *C) {
35943594
}
35953595

35963596
template <typename Derived>
3597-
bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
3597+
bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *C) {
3598+
TRY_TO(TraverseStmt(C->getCondition()));
35983599
return true;
35993600
}
36003601

clang/include/clang/Sema/SemaOpenMP.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,8 @@ class SemaOpenMP : public SemaBase {
10221022
SourceLocation EndLoc);
10231023
/// Called on well-formed 'nowait' clause.
10241024
OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc,
1025-
SourceLocation EndLoc);
1025+
SourceLocation EndLoc,
1026+
SourceLocation LParenLoc, Expr *Condition);
10261027
/// Called on well-formed 'untied' clause.
10271028
OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc,
10281029
SourceLocation EndLoc);

clang/lib/AST/OpenMPClause.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,12 @@ OMPClause::child_range OMPIfClause::used_children() {
309309
return child_range(&Condition, &Condition + 1);
310310
}
311311

312+
OMPClause::child_range OMPNowaitClause::used_children() {
313+
if (Condition)
314+
return child_range(&Condition, &Condition + 1);
315+
return children();
316+
}
317+
312318
OMPClause::child_range OMPGrainsizeClause::used_children() {
313319
if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
314320
return child_range(C, C + 1);
@@ -2113,8 +2119,13 @@ void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
21132119
}
21142120
}
21152121

2116-
void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
2122+
void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *Node) {
21172123
OS << "nowait";
2124+
if (auto *Cond = Node->getCondition()) {
2125+
OS << "(";
2126+
Cond->printPretty(OS, nullptr, Policy, 0);
2127+
OS << ")";
2128+
}
21182129
}
21192130

21202131
void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {

clang/lib/AST/StmtProfile.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,10 @@ void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *C) {
585585
Profiler->VisitStmt(Num);
586586
}
587587

588-
void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
588+
void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *C) {
589+
if (C->getCondition())
590+
Profiler->VisitStmt(C->getCondition());
591+
}
589592

590593
void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {}
591594

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3311,7 +3311,11 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
33113311
ErrorFound = true;
33123312
}
33133313

3314-
Clause = ParseOpenMPClause(CKind, WrongDirective);
3314+
if (CKind == OMPC_nowait && PP.LookAhead(/*N=*/0).is(tok::l_paren) &&
3315+
getLangOpts().OpenMP >= 60)
3316+
Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3317+
else
3318+
Clause = ParseOpenMPClause(CKind, WrongDirective);
33153319
break;
33163320
case OMPC_self_maps:
33173321
// OpenMP [6.0, self_maps clause]

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16491,6 +16491,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
1649116491
case OMPC_ordered:
1649216492
Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
1649316493
break;
16494+
case OMPC_nowait:
16495+
Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc, LParenLoc, Expr);
16496+
break;
1649416497
case OMPC_priority:
1649516498
Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
1649616499
break;
@@ -16546,7 +16549,6 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
1654616549
case OMPC_aligned:
1654716550
case OMPC_copyin:
1654816551
case OMPC_copyprivate:
16549-
case OMPC_nowait:
1655016552
case OMPC_untied:
1655116553
case OMPC_mergeable:
1655216554
case OMPC_threadprivate:
@@ -17955,7 +17957,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPClause(OpenMPClauseKind Kind,
1795517957
Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
1795617958
break;
1795717959
case OMPC_nowait:
17958-
Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
17960+
Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc,
17961+
/*LParenLoc=*/SourceLocation(),
17962+
/*Condition=*/nullptr);
1795917963
break;
1796017964
case OMPC_untied:
1796117965
Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
@@ -18107,9 +18111,24 @@ OMPClause *SemaOpenMP::ActOnOpenMPClause(OpenMPClauseKind Kind,
1810718111
}
1810818112

1810918113
OMPClause *SemaOpenMP::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
18110-
SourceLocation EndLoc) {
18114+
SourceLocation EndLoc,
18115+
SourceLocation LParenLoc,
18116+
Expr *Condition) {
18117+
Expr *ValExpr = Condition;
18118+
if (Condition && LParenLoc.isValid()) {
18119+
if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
18120+
!Condition->isInstantiationDependent() &&
18121+
!Condition->containsUnexpandedParameterPack()) {
18122+
ExprResult Val = SemaRef.CheckBooleanCondition(StartLoc, Condition);
18123+
if (Val.isInvalid())
18124+
return nullptr;
18125+
18126+
ValExpr = Val.get();
18127+
}
18128+
}
1811118129
DSAStack->setNowaitRegion();
18112-
return new (getASTContext()) OMPNowaitClause(StartLoc, EndLoc);
18130+
return new (getASTContext())
18131+
OMPNowaitClause(ValExpr, StartLoc, LParenLoc, EndLoc);
1811318132
}
1811418133

1811518134
OMPClause *SemaOpenMP::ActOnOpenMPUntiedClause(SourceLocation StartLoc,

clang/lib/Sema/TreeTransform.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,6 +1865,17 @@ class TreeTransform {
18651865
LParenLoc, Num);
18661866
}
18671867

1868+
/// Build a new OpenMP 'nowait' clause.
1869+
///
1870+
/// By default, performs semantic analysis to build the new OpenMP clause.
1871+
/// Subclasses may override this routine to provide different behavior.
1872+
OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,
1873+
SourceLocation LParenLoc,
1874+
SourceLocation EndLoc) {
1875+
return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,
1876+
LParenLoc, Condition);
1877+
}
1878+
18681879
/// Build a new OpenMP 'private' clause.
18691880
///
18701881
/// By default, performs semantic analysis to build the new OpenMP clause.
@@ -10612,8 +10623,14 @@ TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
1061210623
template <typename Derived>
1061310624
OMPClause *
1061410625
TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10615-
// No need to rebuild this clause, no template-dependent parameters.
10616-
return C;
10626+
ExprResult Cond;
10627+
if (auto *Condition = C->getCondition()) {
10628+
Cond = getDerived().TransformExpr(Condition);
10629+
if (Cond.isInvalid())
10630+
return nullptr;
10631+
}
10632+
return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
10633+
C->getLParenLoc(), C->getEndLoc());
1061710634
}
1061810635

1061910636
template <typename Derived>

0 commit comments

Comments
 (0)