[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Erich Keane via cfe-commits

https://github.com/erichkeane closed 
https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Erich Keane via cfe-commits

https://github.com/erichkeane updated 
https://github.com/llvm/llvm-project/pull/89151

>From d3894971090921b92c71ba5a18151cb2033c8cfa Mon Sep 17 00:00:00 2001
From: erichkeane 
Date: Tue, 16 Apr 2024 09:43:55 -0700
Subject: [PATCH 1/7] [OpenACC] Implement 'num_workers' clause for compute
 constructs

This clause just takes an 'int expr', which is not optional.  This patch
implements the clause on compute constructs.
---
 clang/include/clang/AST/OpenACCClause.h   |  56 
 .../clang/Basic/DiagnosticSemaKinds.td|  12 +
 clang/include/clang/Basic/OpenACCClauses.def  |   1 +
 clang/include/clang/Parse/Parser.h|   9 +-
 clang/include/clang/Sema/SemaOpenACC.h|  36 ++-
 clang/lib/AST/OpenACCClause.cpp   |  26 ++
 clang/lib/AST/StmtProfile.cpp |   7 +
 clang/lib/AST/TextNodeDumper.cpp  |   1 +
 clang/lib/Parse/ParseOpenACC.cpp  |  57 ++--
 clang/lib/Sema/SemaOpenACC.cpp| 122 +
 clang/lib/Sema/TreeTransform.h|  23 ++
 clang/lib/Serialization/ASTReader.cpp |   7 +-
 clang/lib/Serialization/ASTWriter.cpp |   7 +-
 clang/test/ParserOpenACC/parse-clauses.c  |   2 -
 .../compute-construct-intexpr-clause-ast.cpp  | 255 ++
 .../compute-construct-num_workers-clause.c|  33 +++
 .../compute-construct-num_workers-clause.cpp  | 133 +
 clang/tools/libclang/CIndex.cpp   |   4 +
 18 files changed, 764 insertions(+), 27 deletions(-)
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.c
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp

diff --git a/clang/include/clang/AST/OpenACCClause.h 
b/clang/include/clang/AST/OpenACCClause.h
index 07587849eb1219..7a60620d5875c5 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -156,6 +156,62 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;
+
+  protected:
+OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
+  SourceLocation LParenLoc,
+  ArrayRef IntExprs, SourceLocation EndLoc)
+: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
+  IntExprs(IntExprs) {}
+
+/// Gets the entire list of integer expressions, but leave it to the
+/// individual clauses to expose this how they'd like.
+llvm::ArrayRef getIntExprs() const { return IntExprs; }
+
+  public:
+  child_range children() {
+return child_range(reinterpret_cast(IntExprs.begin()),
+   reinterpret_cast(IntExprs.end()));
+  }
+
+  const_child_range children() const {
+child_range Children =
+const_cast(this)->children();
+return const_child_range(Children.begin(), Children.end());
+  }
+};
+
+/// A more restrictive version of the IntExprs version that exposes a single
+/// integer expression.
+class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
+  protected:
+OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation 
BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr,
+   SourceLocation EndLoc)
+: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, IntExpr, EndLoc) {}
+
+  public:
+bool hasIntExpr() const { return !getIntExprs().empty(); }
+const Expr *getIntExpr() const {
+  return hasIntExpr() ? getIntExprs()[0] : nullptr;
+}
+Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; }
+};
+
+class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
+  OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+  Expr *IntExpr, SourceLocation EndLoc);
+  public:
+static OpenACCNumWorkersClause *
+Create(const ASTContext , SourceLocation BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc);
+};
+
 template  class OpenACCClauseVisitor {
   Impl () { return static_cast(*this); }
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 30a8543489f48e..5ac1b3dc6233a3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12268,4 +12268,16 @@ def warn_acc_if_self_conflict
 : Warning<"OpenACC construct 'self' has no effect when an 'if' clause "
   "evaluates to true">,

[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Alexey Bataev via cfe-commits

https://github.com/alexey-bataev approved this pull request.

LG

https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Erich Keane via cfe-commits


@@ -156,6 +156,64 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;

erichkeane wrote:

Ok, removed the type, so we now just store the info in the 'single expr' base 
class and reference it from there.

https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Erich Keane via cfe-commits

https://github.com/erichkeane updated 
https://github.com/llvm/llvm-project/pull/89151

>From d3894971090921b92c71ba5a18151cb2033c8cfa Mon Sep 17 00:00:00 2001
From: erichkeane 
Date: Tue, 16 Apr 2024 09:43:55 -0700
Subject: [PATCH 1/6] [OpenACC] Implement 'num_workers' clause for compute
 constructs

This clause just takes an 'int expr', which is not optional.  This patch
implements the clause on compute constructs.
---
 clang/include/clang/AST/OpenACCClause.h   |  56 
 .../clang/Basic/DiagnosticSemaKinds.td|  12 +
 clang/include/clang/Basic/OpenACCClauses.def  |   1 +
 clang/include/clang/Parse/Parser.h|   9 +-
 clang/include/clang/Sema/SemaOpenACC.h|  36 ++-
 clang/lib/AST/OpenACCClause.cpp   |  26 ++
 clang/lib/AST/StmtProfile.cpp |   7 +
 clang/lib/AST/TextNodeDumper.cpp  |   1 +
 clang/lib/Parse/ParseOpenACC.cpp  |  57 ++--
 clang/lib/Sema/SemaOpenACC.cpp| 122 +
 clang/lib/Sema/TreeTransform.h|  23 ++
 clang/lib/Serialization/ASTReader.cpp |   7 +-
 clang/lib/Serialization/ASTWriter.cpp |   7 +-
 clang/test/ParserOpenACC/parse-clauses.c  |   2 -
 .../compute-construct-intexpr-clause-ast.cpp  | 255 ++
 .../compute-construct-num_workers-clause.c|  33 +++
 .../compute-construct-num_workers-clause.cpp  | 133 +
 clang/tools/libclang/CIndex.cpp   |   4 +
 18 files changed, 764 insertions(+), 27 deletions(-)
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.c
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp

diff --git a/clang/include/clang/AST/OpenACCClause.h 
b/clang/include/clang/AST/OpenACCClause.h
index 07587849eb1219..7a60620d5875c5 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -156,6 +156,62 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;
+
+  protected:
+OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
+  SourceLocation LParenLoc,
+  ArrayRef IntExprs, SourceLocation EndLoc)
+: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
+  IntExprs(IntExprs) {}
+
+/// Gets the entire list of integer expressions, but leave it to the
+/// individual clauses to expose this how they'd like.
+llvm::ArrayRef getIntExprs() const { return IntExprs; }
+
+  public:
+  child_range children() {
+return child_range(reinterpret_cast(IntExprs.begin()),
+   reinterpret_cast(IntExprs.end()));
+  }
+
+  const_child_range children() const {
+child_range Children =
+const_cast(this)->children();
+return const_child_range(Children.begin(), Children.end());
+  }
+};
+
+/// A more restrictive version of the IntExprs version that exposes a single
+/// integer expression.
+class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
+  protected:
+OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation 
BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr,
+   SourceLocation EndLoc)
+: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, IntExpr, EndLoc) {}
+
+  public:
+bool hasIntExpr() const { return !getIntExprs().empty(); }
+const Expr *getIntExpr() const {
+  return hasIntExpr() ? getIntExprs()[0] : nullptr;
+}
+Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; }
+};
+
+class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
+  OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+  Expr *IntExpr, SourceLocation EndLoc);
+  public:
+static OpenACCNumWorkersClause *
+Create(const ASTContext , SourceLocation BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc);
+};
+
 template  class OpenACCClauseVisitor {
   Impl () { return static_cast(*this); }
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 30a8543489f48e..5ac1b3dc6233a3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12268,4 +12268,16 @@ def warn_acc_if_self_conflict
 : Warning<"OpenACC construct 'self' has no effect when an 'if' clause "
   "evaluates to true">,

[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Alexey Bataev via cfe-commits


@@ -156,6 +156,64 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;

alexey-bataev wrote:

Better to have here just a single expr and later just rework it for trailing 
storage, I think.

https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Erich Keane via cfe-commits

erichkeane wrote:

Sorry for the extra two updates, I found those two while working on the next 
clause :) 

https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Erich Keane via cfe-commits


@@ -156,6 +156,64 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;

erichkeane wrote:

There are OTHER clauses coming in the future that use multiple `Exprs`, so I'm 
designing the class hierarchy to handle that as well.  The intent is for THIS 
class to be the base for all that have `IntExprs`, but the one I am 
implementing NOW is only a 'single' Expr*.

So my intent is that I WILL use the trailing-storage on the ones that take 
multiples (and have now done the changes so that will be possible, by making 
this an arrayref), but as an optimization, just use a DataMember for the 
'special cases' where there is only 1.

https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Alexey Bataev via cfe-commits


@@ -156,6 +156,64 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;

alexey-bataev wrote:

Why do you need a vector then?

https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Erich Keane via cfe-commits


@@ -156,6 +156,64 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;

erichkeane wrote:

I moved this closer to tail-allocation.  I didn't see value in doing this with 
tail-allocation in THIS case because it is just a single `Expr`.  However, I 
changed this class to work correctly when I inherit from it directly with 
'trailing' storage.

https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Erich Keane via cfe-commits

https://github.com/erichkeane updated 
https://github.com/llvm/llvm-project/pull/89151

>From d3894971090921b92c71ba5a18151cb2033c8cfa Mon Sep 17 00:00:00 2001
From: erichkeane 
Date: Tue, 16 Apr 2024 09:43:55 -0700
Subject: [PATCH 1/3] [OpenACC] Implement 'num_workers' clause for compute
 constructs

This clause just takes an 'int expr', which is not optional.  This patch
implements the clause on compute constructs.
---
 clang/include/clang/AST/OpenACCClause.h   |  56 
 .../clang/Basic/DiagnosticSemaKinds.td|  12 +
 clang/include/clang/Basic/OpenACCClauses.def  |   1 +
 clang/include/clang/Parse/Parser.h|   9 +-
 clang/include/clang/Sema/SemaOpenACC.h|  36 ++-
 clang/lib/AST/OpenACCClause.cpp   |  26 ++
 clang/lib/AST/StmtProfile.cpp |   7 +
 clang/lib/AST/TextNodeDumper.cpp  |   1 +
 clang/lib/Parse/ParseOpenACC.cpp  |  57 ++--
 clang/lib/Sema/SemaOpenACC.cpp| 122 +
 clang/lib/Sema/TreeTransform.h|  23 ++
 clang/lib/Serialization/ASTReader.cpp |   7 +-
 clang/lib/Serialization/ASTWriter.cpp |   7 +-
 clang/test/ParserOpenACC/parse-clauses.c  |   2 -
 .../compute-construct-intexpr-clause-ast.cpp  | 255 ++
 .../compute-construct-num_workers-clause.c|  33 +++
 .../compute-construct-num_workers-clause.cpp  | 133 +
 clang/tools/libclang/CIndex.cpp   |   4 +
 18 files changed, 764 insertions(+), 27 deletions(-)
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.c
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp

diff --git a/clang/include/clang/AST/OpenACCClause.h 
b/clang/include/clang/AST/OpenACCClause.h
index 07587849eb1219..7a60620d5875c5 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -156,6 +156,62 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;
+
+  protected:
+OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
+  SourceLocation LParenLoc,
+  ArrayRef IntExprs, SourceLocation EndLoc)
+: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
+  IntExprs(IntExprs) {}
+
+/// Gets the entire list of integer expressions, but leave it to the
+/// individual clauses to expose this how they'd like.
+llvm::ArrayRef getIntExprs() const { return IntExprs; }
+
+  public:
+  child_range children() {
+return child_range(reinterpret_cast(IntExprs.begin()),
+   reinterpret_cast(IntExprs.end()));
+  }
+
+  const_child_range children() const {
+child_range Children =
+const_cast(this)->children();
+return const_child_range(Children.begin(), Children.end());
+  }
+};
+
+/// A more restrictive version of the IntExprs version that exposes a single
+/// integer expression.
+class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
+  protected:
+OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation 
BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr,
+   SourceLocation EndLoc)
+: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, IntExpr, EndLoc) {}
+
+  public:
+bool hasIntExpr() const { return !getIntExprs().empty(); }
+const Expr *getIntExpr() const {
+  return hasIntExpr() ? getIntExprs()[0] : nullptr;
+}
+Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; }
+};
+
+class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
+  OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+  Expr *IntExpr, SourceLocation EndLoc);
+  public:
+static OpenACCNumWorkersClause *
+Create(const ASTContext , SourceLocation BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc);
+};
+
 template  class OpenACCClauseVisitor {
   Impl () { return static_cast(*this); }
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 30a8543489f48e..5ac1b3dc6233a3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12268,4 +12268,16 @@ def warn_acc_if_self_conflict
 : Warning<"OpenACC construct 'self' has no effect when an 'if' clause "
   "evaluates to true">,

[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-18 Thread Alexey Bataev via cfe-commits


@@ -156,6 +156,64 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;

alexey-bataev wrote:

Use tail-allocation instead

https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-17 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 693a458287d019c5c6a66fe3019d099df2978cdb 
d3894971090921b92c71ba5a18151cb2033c8cfa -- 
clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.c 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp 
clang/include/clang/AST/OpenACCClause.h clang/include/clang/Parse/Parser.h 
clang/include/clang/Sema/SemaOpenACC.h clang/lib/AST/OpenACCClause.cpp 
clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp 
clang/lib/Parse/ParseOpenACC.cpp clang/lib/Sema/SemaOpenACC.cpp 
clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp 
clang/lib/Serialization/ASTWriter.cpp clang/test/ParserOpenACC/parse-clauses.c 
clang/tools/libclang/CIndex.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/AST/OpenACCClause.h 
b/clang/include/clang/AST/OpenACCClause.h
index 7a60620d58..aeb359ab7e 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -162,18 +162,18 @@ public:
 class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
   llvm::SmallVector IntExprs;
 
-  protected:
-OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
-  SourceLocation LParenLoc,
-  ArrayRef IntExprs, SourceLocation EndLoc)
-: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
-  IntExprs(IntExprs) {}
-
-/// Gets the entire list of integer expressions, but leave it to the
-/// individual clauses to expose this how they'd like.
-llvm::ArrayRef getIntExprs() const { return IntExprs; }
-
-  public:
+protected:
+  OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
+SourceLocation LParenLoc, ArrayRef 
IntExprs,
+SourceLocation EndLoc)
+  : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
+IntExprs(IntExprs) {}
+
+  /// Gets the entire list of integer expressions, but leave it to the
+  /// individual clauses to expose this how they'd like.
+  llvm::ArrayRef getIntExprs() const { return IntExprs; }
+
+public:
   child_range children() {
 return child_range(reinterpret_cast(IntExprs.begin()),
reinterpret_cast(IntExprs.end()));
@@ -189,27 +189,29 @@ class OpenACCClauseWithIntExprs : public 
OpenACCClauseWithParams {
 /// A more restrictive version of the IntExprs version that exposes a single
 /// integer expression.
 class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
-  protected:
-OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation 
BeginLoc,
-   SourceLocation LParenLoc, Expr *IntExpr,
-   SourceLocation EndLoc)
-: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, IntExpr, EndLoc) {}
-
-  public:
-bool hasIntExpr() const { return !getIntExprs().empty(); }
-const Expr *getIntExpr() const {
-  return hasIntExpr() ? getIntExprs()[0] : nullptr;
-}
-Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; }
+protected:
+  OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc,
+ SourceLocation LParenLoc, Expr *IntExpr,
+ SourceLocation EndLoc)
+  : OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, IntExpr, EndLoc) {}
+
+public:
+  bool hasIntExpr() const { return !getIntExprs().empty(); }
+  const Expr *getIntExpr() const {
+return hasIntExpr() ? getIntExprs()[0] : nullptr;
+  }
+  Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; }
 };
 
 class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
   OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
   Expr *IntExpr, SourceLocation EndLoc);
-  public:
-static OpenACCNumWorkersClause *
-Create(const ASTContext , SourceLocation BeginLoc,
-   SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc);
+
+public:
+  static OpenACCNumWorkersClause *Create(const ASTContext ,
+ SourceLocation BeginLoc,
+ SourceLocation LParenLoc,
+ Expr *IntExpr, SourceLocation EndLoc);
 };
 
 template  class OpenACCClauseVisitor {
diff --git a/clang/include/clang/Sema/SemaOpenACC.h 
b/clang/include/clang/Sema/SemaOpenACC.h
index eb461fa7db..b995edebe8 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -105,7 +105,7 @@ public:
 }
 
 ArrayRef getIntExprs() const {
-  

[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-17 Thread Erich Keane via cfe-commits

https://github.com/erichkeane updated 
https://github.com/llvm/llvm-project/pull/89151

>From d3894971090921b92c71ba5a18151cb2033c8cfa Mon Sep 17 00:00:00 2001
From: erichkeane 
Date: Tue, 16 Apr 2024 09:43:55 -0700
Subject: [PATCH 1/2] [OpenACC] Implement 'num_workers' clause for compute
 constructs

This clause just takes an 'int expr', which is not optional.  This patch
implements the clause on compute constructs.
---
 clang/include/clang/AST/OpenACCClause.h   |  56 
 .../clang/Basic/DiagnosticSemaKinds.td|  12 +
 clang/include/clang/Basic/OpenACCClauses.def  |   1 +
 clang/include/clang/Parse/Parser.h|   9 +-
 clang/include/clang/Sema/SemaOpenACC.h|  36 ++-
 clang/lib/AST/OpenACCClause.cpp   |  26 ++
 clang/lib/AST/StmtProfile.cpp |   7 +
 clang/lib/AST/TextNodeDumper.cpp  |   1 +
 clang/lib/Parse/ParseOpenACC.cpp  |  57 ++--
 clang/lib/Sema/SemaOpenACC.cpp| 122 +
 clang/lib/Sema/TreeTransform.h|  23 ++
 clang/lib/Serialization/ASTReader.cpp |   7 +-
 clang/lib/Serialization/ASTWriter.cpp |   7 +-
 clang/test/ParserOpenACC/parse-clauses.c  |   2 -
 .../compute-construct-intexpr-clause-ast.cpp  | 255 ++
 .../compute-construct-num_workers-clause.c|  33 +++
 .../compute-construct-num_workers-clause.cpp  | 133 +
 clang/tools/libclang/CIndex.cpp   |   4 +
 18 files changed, 764 insertions(+), 27 deletions(-)
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.c
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp

diff --git a/clang/include/clang/AST/OpenACCClause.h 
b/clang/include/clang/AST/OpenACCClause.h
index 07587849eb1219..7a60620d5875c5 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -156,6 +156,62 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;
+
+  protected:
+OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
+  SourceLocation LParenLoc,
+  ArrayRef IntExprs, SourceLocation EndLoc)
+: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
+  IntExprs(IntExprs) {}
+
+/// Gets the entire list of integer expressions, but leave it to the
+/// individual clauses to expose this how they'd like.
+llvm::ArrayRef getIntExprs() const { return IntExprs; }
+
+  public:
+  child_range children() {
+return child_range(reinterpret_cast(IntExprs.begin()),
+   reinterpret_cast(IntExprs.end()));
+  }
+
+  const_child_range children() const {
+child_range Children =
+const_cast(this)->children();
+return const_child_range(Children.begin(), Children.end());
+  }
+};
+
+/// A more restrictive version of the IntExprs version that exposes a single
+/// integer expression.
+class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
+  protected:
+OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation 
BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr,
+   SourceLocation EndLoc)
+: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, IntExpr, EndLoc) {}
+
+  public:
+bool hasIntExpr() const { return !getIntExprs().empty(); }
+const Expr *getIntExpr() const {
+  return hasIntExpr() ? getIntExprs()[0] : nullptr;
+}
+Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; }
+};
+
+class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
+  OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+  Expr *IntExpr, SourceLocation EndLoc);
+  public:
+static OpenACCNumWorkersClause *
+Create(const ASTContext , SourceLocation BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc);
+};
+
 template  class OpenACCClauseVisitor {
   Impl () { return static_cast(*this); }
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 30a8543489f48e..5ac1b3dc6233a3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12268,4 +12268,16 @@ def warn_acc_if_self_conflict
 : Warning<"OpenACC construct 'self' has no effect when an 'if' clause "
   "evaluates to true">,

[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-17 Thread Erich Keane via cfe-commits


@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+struct NotConvertible{} NC;
+struct Incomplete *SomeIncomplete; // #INCOMPLETE
+enum E{} SomeE;
+enum class E2{} SomeE2;
+
+struct CorrectConvert {
+  operator int();
+} Convert;
+
+struct ExplicitConvertOnly {
+  explicit operator int() const; // #EXPL_CONV
+} Explicit;
+
+struct AmbiguousConvert{
+  operator int(); // #AMBIG_INT
+  operator short(); // #AMBIG_SHORT
+  operator float();
+} Ambiguous;
+
+void Test() {
+#pragma acc parallel num_workers(1)
+  while(1);
+#pragma acc kernels num_workers(1)
+  while(1);
+
+  // expected-error@+1{{OpenACC clause 'num_workers' requires expression of 
integer type ('struct NotConvertible' invalid}}
+#pragma acc parallel num_workers(NC)
+  while(1);
+
+  // expected-error@+2{{OpenACC integer expression has incomplete class type 
'struct Incomplete'}}
+  // expected-note@#INCOMPLETE{{forward declaration of 'Incomplete'}}
+#pragma acc kernels num_workers(*SomeIncomplete)
+  while(1);
+
+#pragma acc parallel num_workers(SomeE)
+  while(1);
+
+  // expected-error@+1{{OpenACC clause 'num_workers' requires expression of 
integer type ('enum E2' invalid}}
+#pragma acc kernels num_workers(SomeE2)
+  while(1);
+
+#pragma acc parallel num_workers(Convert)
+  while(1);
+
+  // expected-error@+2{{OpenACC integer expression type 'struct 
ExplicitConvertOnly' requires explicit conversion to 'int'}}
+  // expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
+#pragma acc kernels num_workers(Explicit)
+  while(1);
+
+  // expected-error@+3{{multiple conversions from expression type 'struct 
AmbiguousConvert' to an integral type}}
+  // expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
+  // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}}
+#pragma acc parallel num_workers(Ambiguous)
+  while(1);
+}
+
+struct HasInt {
+  using IntTy = int;
+  using ShortTy = short;
+  static constexpr int value = 1;
+  static constexpr AmbiguousConvert ACValue;
+  static constexpr ExplicitConvertOnly EXValue;
+
+  operator char();
+};
+
+template
+void TestInst() {
+
+  // expected-error@+1{{no member named 'Invalid' in 'HasInt'}}
+#pragma acc parallel num_workers(HasInt::Invalid)
+  while (1);
+
+  // expected-error@+2{{no member named 'Invalid' in 'HasInt'}}
+  // expected-note@#INST{{in instantiation of function template specialization 
'TestInst' requested here}}
+#pragma acc kernels num_workers(T::Invalid)
+  while (1);
+
+  // expected-error@+3{{multiple conversions from expression type 'const 
AmbiguousConvert' to an integral type}}
+  // expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
+  // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}}
+#pragma acc parallel num_workers(HasInt::ACValue)
+  while (1);
+
+  // expected-error@+3{{multiple conversions from expression type 'const 
AmbiguousConvert' to an integral type}}
+  // expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
+  // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}}
+#pragma acc kernels num_workers(T::ACValue)
+  while (1);
+
+  // expected-error@+2{{OpenACC integer expression type 'const 
ExplicitConvertOnly' requires explicit conversion to 'int'}}
+  // expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
+#pragma acc parallel num_workers(HasInt::EXValue)

erichkeane wrote:

Note: this is expected to diagnose the above error/note 2x until this patch is 
committed: https://github.com/llvm/llvm-project/pull/89142

as it uses the same infrastructure.  I'll ensure these are committed in the 
correct order.

https://github.com/llvm/llvm-project/pull/89151
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-modules

Author: Erich Keane (erichkeane)


Changes

This clause just takes an 'int expr', which is not optional.  This patch 
implements the clause on compute constructs.

---

Patch is 44.13 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/89151.diff


18 Files Affected:

- (modified) clang/include/clang/AST/OpenACCClause.h (+56) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+12) 
- (modified) clang/include/clang/Basic/OpenACCClauses.def (+1) 
- (modified) clang/include/clang/Parse/Parser.h (+5-4) 
- (modified) clang/include/clang/Sema/SemaOpenACC.h (+34-2) 
- (modified) clang/lib/AST/OpenACCClause.cpp (+26) 
- (modified) clang/lib/AST/StmtProfile.cpp (+7) 
- (modified) clang/lib/AST/TextNodeDumper.cpp (+1) 
- (modified) clang/lib/Parse/ParseOpenACC.cpp (+40-17) 
- (modified) clang/lib/Sema/SemaOpenACC.cpp (+122) 
- (modified) clang/lib/Sema/TreeTransform.h (+23) 
- (modified) clang/lib/Serialization/ASTReader.cpp (+6-1) 
- (modified) clang/lib/Serialization/ASTWriter.cpp (+6-1) 
- (modified) clang/test/ParserOpenACC/parse-clauses.c (-2) 
- (added) clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp 
(+255) 
- (added) clang/test/SemaOpenACC/compute-construct-num_workers-clause.c (+33) 
- (added) clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp 
(+133) 
- (modified) clang/tools/libclang/CIndex.cpp (+4) 


``diff
diff --git a/clang/include/clang/AST/OpenACCClause.h 
b/clang/include/clang/AST/OpenACCClause.h
index 07587849eb1219..7a60620d5875c5 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -156,6 +156,62 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;
+
+  protected:
+OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
+  SourceLocation LParenLoc,
+  ArrayRef IntExprs, SourceLocation EndLoc)
+: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
+  IntExprs(IntExprs) {}
+
+/// Gets the entire list of integer expressions, but leave it to the
+/// individual clauses to expose this how they'd like.
+llvm::ArrayRef getIntExprs() const { return IntExprs; }
+
+  public:
+  child_range children() {
+return child_range(reinterpret_cast(IntExprs.begin()),
+   reinterpret_cast(IntExprs.end()));
+  }
+
+  const_child_range children() const {
+child_range Children =
+const_cast(this)->children();
+return const_child_range(Children.begin(), Children.end());
+  }
+};
+
+/// A more restrictive version of the IntExprs version that exposes a single
+/// integer expression.
+class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
+  protected:
+OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation 
BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr,
+   SourceLocation EndLoc)
+: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, IntExpr, EndLoc) {}
+
+  public:
+bool hasIntExpr() const { return !getIntExprs().empty(); }
+const Expr *getIntExpr() const {
+  return hasIntExpr() ? getIntExprs()[0] : nullptr;
+}
+Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; }
+};
+
+class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
+  OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+  Expr *IntExpr, SourceLocation EndLoc);
+  public:
+static OpenACCNumWorkersClause *
+Create(const ASTContext , SourceLocation BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc);
+};
+
 template  class OpenACCClauseVisitor {
   Impl () { return static_cast(*this); }
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 30a8543489f48e..5ac1b3dc6233a3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12268,4 +12268,16 @@ def warn_acc_if_self_conflict
 : Warning<"OpenACC construct 'self' has no effect when an 'if' clause "
   "evaluates to true">,
   InGroup>;
+def err_acc_int_expr_requires_integer
+: Error<"OpenACC %select{clause|directive}0 '%1' requires expression of "
+"integer type (%2 invalid)">;
+def err_acc_int_expr_incomplete_class_type
+: Error<"OpenACC integer expression has incomplete class type %0">;

[clang] [OpenACC] Implement 'num_workers' clause for compute constructs (PR #89151)

2024-04-17 Thread Erich Keane via cfe-commits

https://github.com/erichkeane created 
https://github.com/llvm/llvm-project/pull/89151

This clause just takes an 'int expr', which is not optional.  This patch 
implements the clause on compute constructs.

>From d3894971090921b92c71ba5a18151cb2033c8cfa Mon Sep 17 00:00:00 2001
From: erichkeane 
Date: Tue, 16 Apr 2024 09:43:55 -0700
Subject: [PATCH] [OpenACC] Implement 'num_workers' clause for compute
 constructs

This clause just takes an 'int expr', which is not optional.  This patch
implements the clause on compute constructs.
---
 clang/include/clang/AST/OpenACCClause.h   |  56 
 .../clang/Basic/DiagnosticSemaKinds.td|  12 +
 clang/include/clang/Basic/OpenACCClauses.def  |   1 +
 clang/include/clang/Parse/Parser.h|   9 +-
 clang/include/clang/Sema/SemaOpenACC.h|  36 ++-
 clang/lib/AST/OpenACCClause.cpp   |  26 ++
 clang/lib/AST/StmtProfile.cpp |   7 +
 clang/lib/AST/TextNodeDumper.cpp  |   1 +
 clang/lib/Parse/ParseOpenACC.cpp  |  57 ++--
 clang/lib/Sema/SemaOpenACC.cpp| 122 +
 clang/lib/Sema/TreeTransform.h|  23 ++
 clang/lib/Serialization/ASTReader.cpp |   7 +-
 clang/lib/Serialization/ASTWriter.cpp |   7 +-
 clang/test/ParserOpenACC/parse-clauses.c  |   2 -
 .../compute-construct-intexpr-clause-ast.cpp  | 255 ++
 .../compute-construct-num_workers-clause.c|  33 +++
 .../compute-construct-num_workers-clause.cpp  | 133 +
 clang/tools/libclang/CIndex.cpp   |   4 +
 18 files changed, 764 insertions(+), 27 deletions(-)
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.c
 create mode 100644 
clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp

diff --git a/clang/include/clang/AST/OpenACCClause.h 
b/clang/include/clang/AST/OpenACCClause.h
index 07587849eb1219..7a60620d5875c5 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -156,6 +156,62 @@ class OpenACCSelfClause : public 
OpenACCClauseWithCondition {
Expr *ConditionExpr, SourceLocation EndLoc);
 };
 
+/// Represents one of a handful of classes that have integer expressions.
+/// Semantically, many only permit a single expression, with a few that permit
+/// up to 3.
+class OpenACCClauseWithIntExprs : public OpenACCClauseWithParams {
+  llvm::SmallVector IntExprs;
+
+  protected:
+OpenACCClauseWithIntExprs(OpenACCClauseKind K, SourceLocation BeginLoc,
+  SourceLocation LParenLoc,
+  ArrayRef IntExprs, SourceLocation EndLoc)
+: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
+  IntExprs(IntExprs) {}
+
+/// Gets the entire list of integer expressions, but leave it to the
+/// individual clauses to expose this how they'd like.
+llvm::ArrayRef getIntExprs() const { return IntExprs; }
+
+  public:
+  child_range children() {
+return child_range(reinterpret_cast(IntExprs.begin()),
+   reinterpret_cast(IntExprs.end()));
+  }
+
+  const_child_range children() const {
+child_range Children =
+const_cast(this)->children();
+return const_child_range(Children.begin(), Children.end());
+  }
+};
+
+/// A more restrictive version of the IntExprs version that exposes a single
+/// integer expression.
+class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithIntExprs {
+  protected:
+OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation 
BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr,
+   SourceLocation EndLoc)
+: OpenACCClauseWithIntExprs(K, BeginLoc, LParenLoc, IntExpr, EndLoc) {}
+
+  public:
+bool hasIntExpr() const { return !getIntExprs().empty(); }
+const Expr *getIntExpr() const {
+  return hasIntExpr() ? getIntExprs()[0] : nullptr;
+}
+Expr *getIntExpr() { return hasIntExpr() ? getIntExprs()[0] : nullptr; }
+};
+
+class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr {
+  OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+  Expr *IntExpr, SourceLocation EndLoc);
+  public:
+static OpenACCNumWorkersClause *
+Create(const ASTContext , SourceLocation BeginLoc,
+   SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc);
+};
+
 template  class OpenACCClauseVisitor {
   Impl () { return static_cast(*this); }
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 30a8543489f48e..5ac1b3dc6233a3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12268,4 +12268,16 @@ def warn_acc_if_self_conflict