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@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait + + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait clause-list + + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait ( + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait () + + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait () clause-list + + // expected-error@+4{{expected expression}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (devnum: + + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (devnum:) + + // expected-error@+3{{expected expression}} + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (devnum:) clause-list + + // expected-error@+4{{expected ':'}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (devnum: i + j + + // expected-error@+2{{expected ':'}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (devnum: i + j) + + // expected-error@+3{{expected ':'}} + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (devnum: i + j) clause-list + + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (queues: + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (queues:) + + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (queues:) clause-list + + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (devnum: i + j:queues: + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (devnum: i + j:queues:) + + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (devnum: i + j:queues:) clause-list + + // expected-error@+4{{use of undeclared identifier 'devnum'}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (queues:devnum: i + j + + // expected-error@+2{{use of undeclared identifier 'devnum'}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (queues:devnum: i + j) + + // expected-error@+3{{use of undeclared identifier 'devnum'}} + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait (queues:devnum: i + j) clause-list + + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(i, j, 1+1, 3.3 + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(i, j, 1+1, 3.3) + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(i, j, 1+1, 3.3) clause-list + + // expected-error@+4{{expected expression}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(, + + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(,) + + // expected-error@+3{{expected expression}} + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(,) clause-list + + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(queues:i, j, 1+1, 3.3 + + // expected-error@+4{{expected expression}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(queues:i, j, 1+1, 3.3, + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(queues:i, j, 1+1, 3.3) + + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(queues:i, j, 1+1, 3.3) clause-list + + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(devnum:3:i, j, 1+1, 3.3 + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(devnum:3:i, j, 1+1, 3.3) + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(devnum:3:i, j, 1+1, 3.3) clause-list + + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3 + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} + #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3) + // expected-warning@+2{{OpenACC clause parsing not yet implemented}} + // expected-warning@+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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits