[clang] [OpenACC] Implement 'wait' construct parsing (PR #74752)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 7 11:37:34 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Erich Keane (erichkeane)
<details>
<summary>Changes</summary>
The 'wait' construct comes in two forms: one with no parens, the second with a 'wait-argument'. This implements both forms for constructs.
Additionally, the 'wait-argument' parsing is split into its own function because the 'wait clause' can also take the same 'wait-argument'.
---
Full diff: https://github.com/llvm/llvm-project/pull/74752.diff
4 Files Affected:
- (modified) clang/include/clang/Basic/OpenACCKinds.h (+1-1)
- (modified) clang/include/clang/Parse/Parser.h (+1)
- (modified) clang/lib/Parse/ParseOpenACC.cpp (+71)
- (added) clang/test/ParserOpenACC/parse-wait-construct.c (+157)
``````````diff
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index 449a75638b43f5..62c0a4c1a9dea4 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -53,7 +53,7 @@ enum class OpenACCDirectiveKind {
Shutdown,
Set,
Update,
- // FIXME: wait construct.
+ Wait,
// Procedure Calls in Compute Regions.
Routine,
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 32d0b76c35b0d7..06634982351647 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3544,6 +3544,7 @@ class Parser : public CodeCompletionHandler {
void ParseOpenACCCacheVarList();
/// Parses a single variable in a variable list for the 'cache' construct.
bool ParseOpenACCCacheVar();
+ bool ParseOpenACCWaitArgument();
private:
//===--------------------------------------------------------------------===//
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 71cb665a563271..0bdf8da26bb01e 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -56,6 +56,7 @@ OpenACCDirectiveKindEx getOpenACCDirectiveKind(Token Tok) {
.Case("shutdown", OpenACCDirectiveKind::Shutdown)
.Case("set", OpenACCDirectiveKind::Shutdown)
.Case("update", OpenACCDirectiveKind::Update)
+ .Case("wait", OpenACCDirectiveKind::Wait)
.Default(OpenACCDirectiveKind::Invalid);
if (DirKind != OpenACCDirectiveKind::Invalid)
@@ -123,6 +124,8 @@ bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) {
return Tok.getIdentifierInfo()->isStr("set");
case OpenACCDirectiveKind::Update:
return Tok.getIdentifierInfo()->isStr("update");
+ case OpenACCDirectiveKind::Wait:
+ return Tok.getIdentifierInfo()->isStr("wait");
case OpenACCDirectiveKind::Invalid:
return false;
}
@@ -251,6 +254,67 @@ void ParseOpenACCClauseList(Parser &P) {
} // namespace
+/// OpenACC 3.3, section 2.16:
+/// In this section and throughout the specification, the term wait-argument
+/// means:
+/// [ devnum : int-expr : ] [ queues : ] async-argument-list
+bool Parser::ParseOpenACCWaitArgument() {
+ // [devnum : int-expr : ]
+ if (Tok.is(tok::identifier) && NextToken().is(tok::colon) &&
+ Tok.getIdentifierInfo()->isStr("devnum")) {
+ // Consume devnum.
+ ConsumeToken();
+ // Consume colon.
+ ConsumeToken();
+
+ ExprResult IntExpr =
+ getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+ if (IntExpr.isInvalid())
+ return true;
+
+ if (ExpectAndConsume(tok::colon))
+ return true;
+ }
+
+ // [ queues : ]
+ if (Tok.is(tok::identifier) && NextToken().is(tok::colon) &&
+ Tok.getIdentifierInfo()->isStr("queues")) {
+ // Consume queues.
+ ConsumeToken();
+ // Consume colon.
+ ConsumeToken();
+ }
+
+ // OpenACC 3.3, section 2.16:
+ // the term 'async-argument' means a nonnegative scalar integer expression, or
+ // one of the special values 'acc_async_noval' or 'acc_async_sync', as defined
+ // in the C header file and the Fortran opacc module.
+ //
+ // We are parsing this simply as list of assignment expressions (to avoid
+ // comma being troublesome), and will ensure it is an integral type. The
+ // 'special' types are defined as macros, so we can't really check those
+ // (other than perhaps as values at one point?), but the standard does say it
+ // is implementation-defined to use any other negative value.
+ //
+ //
+ bool FirstArg = true;
+ while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
+ if (!FirstArg) {
+ if (ExpectAndConsume(tok::comma))
+ return true;
+ }
+ FirstArg = false;
+
+ ExprResult CurArg =
+ getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+
+ if (CurArg.isInvalid())
+ return true;
+ }
+
+ return false;
+}
+
ExprResult Parser::ParseOpenACCIDExpression() {
ExprResult Res;
if (getLangOpts().CPlusPlus) {
@@ -399,6 +463,13 @@ void Parser::ParseOpenACCDirective() {
// so we can always consume the close.
T.consumeClose();
break;
+ case OpenACCDirectiveKind::Wait:
+ // OpenACC has an optional paren-wrapped 'wait-argument'.
+ if (ParseOpenACCWaitArgument())
+ T.skipToEnd();
+ else
+ T.consumeClose();
+ break;
}
} else if (DirKind == OpenACCDirectiveKind::Cache) {
// Cache's paren var-list is required, so error here if it isn't provided.
diff --git a/clang/test/ParserOpenACC/parse-wait-construct.c b/clang/test/ParserOpenACC/parse-wait-construct.c
new file mode 100644
index 00000000000000..9b210bc7094210
--- /dev/null
+++ b/clang/test/ParserOpenACC/parse-wait-construct.c
@@ -0,0 +1,157 @@
+// RUN: %clang_cc1 %s -verify -fopenacc
+
+void func() {
+ int i, j;
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait
+
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait clause-list
+
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait ()
+
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait () clause-list
+
+ // expected-error at +4{{expected expression}}
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum:
+
+ // expected-error at +2{{expected expression}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum:)
+
+ // expected-error at +3{{expected expression}}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum:) clause-list
+
+ // expected-error at +4{{expected ':'}}
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j
+
+ // expected-error at +2{{expected ':'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j)
+
+ // expected-error at +3{{expected ':'}}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j) clause-list
+
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:)
+
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:) clause-list
+
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j:queues:
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j:queues:)
+
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j:queues:) clause-list
+
+ // expected-error at +4{{use of undeclared identifier 'devnum'}}
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:devnum: i + j
+
+ // expected-error at +2{{use of undeclared identifier 'devnum'}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:devnum: i + j)
+
+ // expected-error at +3{{use of undeclared identifier 'devnum'}}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:devnum: i + j) clause-list
+
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(i, j, 1+1, 3.3
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(i, j, 1+1, 3.3)
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(i, j, 1+1, 3.3) clause-list
+
+ // expected-error at +4{{expected expression}}
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(,
+
+ // expected-error at +2{{expected expression}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(,)
+
+ // expected-error at +3{{expected expression}}
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(,) clause-list
+
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(queues:i, j, 1+1, 3.3
+
+ // expected-error at +4{{expected expression}}
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(queues:i, j, 1+1, 3.3,
+
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(queues:i, j, 1+1, 3.3)
+
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(queues:i, j, 1+1, 3.3) clause-list
+
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:i, j, 1+1, 3.3
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:i, j, 1+1, 3.3)
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:i, j, 1+1, 3.3) clause-list
+
+ // expected-error at +3{{expected ')'}}
+ // expected-note at +2{{to match this '('}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3)
+ // expected-warning at +2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3) clause-list
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/74752
More information about the cfe-commits
mailing list