Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/docs/OpenMPSupport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ implementation.
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| pure directives in DO CONCURRENT | | :none:`unclaimed` | |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| Optional argument for all clauses | :none:`unclaimed` | :none:`unclaimed` | |
| Optional argument for all clauses | :none:`partial` | :none:`In Progress` | Parse/Sema (nowait): https://github.com/llvm/llvm-project/pull/159628 |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| Function references for locator list items | :none:`unclaimed` | :none:`unclaimed` | |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
Expand Down
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,8 @@ OpenMP Support
- Added support for ``defaultmap`` directive implicit-behavior ``private``.
- Added parsing and semantic analysis support for ``groupprivate`` directive.
- Added support for 'omp fuse' directive.
- Updated parsing and semantic analysis support for ``nowait`` clause to accept
optional argument in OpenMP >= 60.

Improvements
^^^^^^^^^^^^
Expand Down
64 changes: 57 additions & 7 deletions clang/include/clang/AST/OpenMPClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -2291,18 +2291,68 @@ 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() {
if (Condition)
return child_range(&Condition, &Condition + 1);
return child_range(child_iterator(), child_iterator());
}

const_child_range children() const {
if (Condition)
return const_child_range(&Condition, &Condition + 1);
return const_child_range(const_child_iterator(), const_child_iterator());
}

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.
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -3594,7 +3594,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;
}

Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,8 @@ class SemaOpenMP : public SemaBase {
SourceLocation EndLoc);
/// Called on well-formed 'nowait' clause.
OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc,
SourceLocation EndLoc);
SourceLocation EndLoc,
SourceLocation LParenLoc, Expr *Condition);
/// Called on well-formed 'untied' clause.
OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc,
SourceLocation EndLoc);
Expand Down
13 changes: 12 additions & 1 deletion clang/lib/AST/OpenMPClause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,12 @@ 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);
return children();
}

OMPClause::child_range OMPGrainsizeClause::used_children() {
if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
return child_range(C, C + 1);
Expand Down Expand Up @@ -2113,8 +2119,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 *) {
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/AST/StmtProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,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 *) {}

Expand Down
6 changes: 5 additions & 1 deletion clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3311,7 +3311,11 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
ErrorFound = true;
}

Clause = ParseOpenMPClause(CKind, WrongDirective);
if (CKind == OMPC_nowait && PP.LookAhead(/*N=*/0).is(tok::l_paren) &&
getLangOpts().OpenMP >= 60)
Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
else
Clause = ParseOpenMPClause(CKind, WrongDirective);
break;
case OMPC_self_maps:
// OpenMP [6.0, self_maps clause]
Expand Down
27 changes: 23 additions & 4 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16491,6 +16491,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;
Expand Down Expand Up @@ -16546,7 +16549,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:
Expand Down Expand Up @@ -17955,7 +17957,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPClause(OpenMPClauseKind Kind,
Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
break;
case OMPC_nowait:
Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc,
/*LParenLoc=*/SourceLocation(),
/*Condition=*/nullptr);
break;
case OMPC_untied:
Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
Expand Down Expand Up @@ -18107,9 +18111,24 @@ 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();
}
}
DSAStack->setNowaitRegion();
return new (getASTContext()) OMPNowaitClause(StartLoc, EndLoc);
return new (getASTContext())
OMPNowaitClause(ValExpr, StartLoc, LParenLoc, EndLoc);
}

OMPClause *SemaOpenMP::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
Expand Down
21 changes: 19 additions & 2 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -1865,6 +1865,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.
Expand Down Expand Up @@ -10612,8 +10623,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>
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11684,7 +11684,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 *) {}

Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7942,7 +7942,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 *) {}

Expand Down
55 changes: 55 additions & 0 deletions clang/test/OpenMP/nowait_ast_print.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// 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
// 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
30 changes: 22 additions & 8 deletions clang/test/OpenMP/target_enter_data_nowait_messages.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fopenmp -fopenmp-version=45 -verify=expected,omp-52-and-earlier -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fopenmp -fopenmp-version=51 -verify=expected,omp-52-and-earlier -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fopenmp -fopenmp-version=52 -verify=expected,omp-52-and-earlier -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fopenmp -fopenmp-version=60 -verify=expected,omp-60-and-later -ferror-limit 100 -o - %s -Wuninitialized

// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fopenmp-simd -fopenmp-version=45 -verify=expected,omp-52-and-earlier -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fopenmp-simd -fopenmp-version=51 -verify=expected,omp-52-and-earlier -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fopenmp-simd -fopenmp-version=52 -verify=expected,omp-52-and-earlier -ferror-limit 100 -o - %s -Wuninitialized
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fopenmp-simd -fopenmp-version=60 -verify=expected,omp-60-and-later -ferror-limit 100 -o - %s -Wuninitialized

int main(int argc, char **argv) {
int i;
Expand All @@ -13,19 +19,27 @@ 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 map(to: i) nowait() // omp-52-and-earlier-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} omp-60-and-later-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( // omp-52-and-earlier-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} omp-60-and-later-error {{expected expression}} omp-60-and-later-error {{expected ')'}} omp-60-and-later-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 (argc)) // omp-52-and-earlier-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} omp-60-and-later-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) // omp-52-and-earlier-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
{}
#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}}
#pragma omp target enter data map(to: i) nowait (argc>> i) // omp-52-and-earlier-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
{}
#pragma omp target enter data nowait map(to: i) nowait // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'nowait' clause}}
#pragma omp target enter data map(to: i) nowait (argv[1] = 2) // omp-52-and-earlier-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} omp-60-and-later-error {{expected ')'}} omp-60-and-later-note {{to match this '('}}
{}
#pragma omp target enter data map(to: i) nowait (argc > 0 ? argv[1] : argv[2]) // omp-52-and-earlier-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
{}
#pragma omp target enter data map(to: i) nowait (S1) // omp-52-and-earlier-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} omp-60-and-later-error {{use of undeclared identifier 'S1'}}
{}
#pragma omp target enter data map(to: i) nowait nowait // omp-52-and-earlier-error {{directive '#pragma omp target enter data' cannot contain more than one 'nowait' clause}} omp-60-and-later-error {{directive '#pragma omp target_enter_data' cannot contain more than one 'nowait' clause}}
{}
#pragma omp target enter data nowait map(to: i) nowait // omp-52-and-earlier-error {{directive '#pragma omp target enter data' cannot contain more than one 'nowait' clause}} omp-60-and-later-error {{directive '#pragma omp target_enter_data' cannot contain more than one 'nowait' clause}}
{}
return 0;
}
Loading