diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h index 6487a95910edd..3f8225c40b641 100644 --- a/clang/include/clang/Basic/OpenACCKinds.h +++ b/clang/include/clang/Basic/OpenACCKinds.h @@ -232,12 +232,15 @@ enum class OpenACCClauseKind { DeviceNum, /// 'default_async' clause, allowed on 'set' construct. DefaultAsync, - /// 'device_type' clause, allowed on Constructs, 'data', 'init', 'shutdown', + /// 'device_type' clause, allowed on Compute, 'data', 'init', 'shutdown', /// 'set', update', 'loop', 'routine', and Combined constructs. DeviceType, /// 'dtype' clause, an alias for 'device_type', stored separately for /// diagnostic purposes. DType, + /// 'async' clause, allowed on Compute, Data, 'update', 'wait', and Combined + /// constructs. + Async, /// Represents an invalid clause, for the purposes of parsing. Invalid, @@ -360,6 +363,9 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out, case OpenACCClauseKind::DType: return Out << "dtype"; + case OpenACCClauseKind::Async: + return Out << "async"; + case OpenACCClauseKind::Invalid: return Out << ""; } diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index ffbde370e8f9c..b9464002dec64 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3589,6 +3589,9 @@ class Parser : public CodeCompletionHandler { ExprResult ParseOpenACCIntExpr(); /// Parses the 'device-type-list', which is a list of identifiers. bool ParseOpenACCDeviceTypeList(); + /// Parses the 'async-argument', which is an integral value with two + /// 'special' values that are likely negative (but come from Macros). + ExprResult ParseOpenACCAsyncArgument(); private: //===--------------------------------------------------------------------===// diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index 9f7e63ecdc951..b7b824d55fbcc 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -89,6 +89,7 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) { return llvm::StringSwitch( Tok.getIdentifierInfo()->getName()) + .Case("async", OpenACCClauseKind::Async) .Case("attach", OpenACCClauseKind::Attach) .Case("auto", OpenACCClauseKind::Auto) .Case("bind", OpenACCClauseKind::Bind) @@ -459,6 +460,7 @@ ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind, case OpenACCClauseKind::Self: return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required : ClauseParensKind::Optional; + case OpenACCClauseKind::Async: case OpenACCClauseKind::Worker: case OpenACCClauseKind::Vector: return ClauseParensKind::Optional; @@ -784,6 +786,12 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind, return true; break; } + case OpenACCClauseKind::Async: { + ExprResult AsyncArg = ParseOpenACCAsyncArgument(); + if (AsyncArg.isInvalid()) + return true; + break; + } default: llvm_unreachable("Not an optional parens type?"); } @@ -793,6 +801,17 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind, return false; } +/// OpenACC 3.3 section 2.16: +/// In this section and throughout the specification, the term async-argument +/// means a nonnegative scalar integer expression (int for C or C++, integer for +/// Fortran), or one of the special values acc_async_noval or acc_async_sync, as +/// defined in the C header file and the Fortran openacc module. The special +/// values are negative values, so as not to conflict with a user-specified +/// nonnegative async-argument. +ExprResult Parser::ParseOpenACCAsyncArgument() { + return getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression()); +} + /// OpenACC 3.3, section 2.16: /// In this section and throughout the specification, the term wait-argument /// means: diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c index faf3caa2b1cfd..b2c5c764e3f3b 100644 --- a/clang/test/ParserOpenACC/parse-clauses.c +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -1019,6 +1019,34 @@ void device_type() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc parallel device_type(ident, auto, int, float) dtype(ident, auto, int, float) +} + +#define acc_async_sync -1 +void AsyncArgument() { + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel async + + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel async() + + // expected-error@+2{{use of undeclared identifier 'invalid'}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel async(invalid) + + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel async(4, 3) + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel async(returns_int()) + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel async(5) + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel async(acc_async_sync) } // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} diff --git a/clang/test/ParserOpenACC/parse-clauses.cpp b/clang/test/ParserOpenACC/parse-clauses.cpp index 07164b5e33794..322080c3c35bc 100644 --- a/clang/test/ParserOpenACC/parse-clauses.cpp +++ b/clang/test/ParserOpenACC/parse-clauses.cpp @@ -17,6 +17,14 @@ void templ() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc parallel vector_length(I) for(;;){} + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel async(T::value) + for(;;){} + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc parallel async(I) + for(;;){} } struct S {