[clang] 62a384c - [OpenACC} Implement 'async' parsing.

via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 24 13:43:39 PST 2024


Author: erichkeane
Date: 2024-01-24T13:43:32-08:00
New Revision: 62a384ca66993b449c5accedbebf7af191fbe52c

URL: https://github.com/llvm/llvm-project/commit/62a384ca66993b449c5accedbebf7af191fbe52c
DIFF: https://github.com/llvm/llvm-project/commit/62a384ca66993b449c5accedbebf7af191fbe52c.diff

LOG: [OpenACC} Implement 'async' parsing.

async just takes an integral value, but it has a little bit of special
rules in sema, so it is implemented slightly differently than int-expr.

This patch implements async parsing.

Added: 
    

Modified: 
    clang/include/clang/Basic/OpenACCKinds.h
    clang/include/clang/Parse/Parser.h
    clang/lib/Parse/ParseOpenACC.cpp
    clang/test/ParserOpenACC/parse-clauses.c
    clang/test/ParserOpenACC/parse-clauses.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index 6487a95910eddc1..3f8225c40b64187 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 << "<invalid>";
   }

diff  --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index ffbde370e8f9c62..b9464002dec646e 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 9f7e63ecdc95186..b7b824d55fbcc95 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -89,6 +89,7 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
 
   return llvm::StringSwitch<OpenACCClauseKind>(
              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 faf3caa2b1cfd4b..b2c5c764e3f3b73 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -1019,6 +1019,34 @@ void device_type() {
 
   // expected-warning at +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 at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel async
+
+  // expected-error at +2{{expected expression}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel async()
+
+  // expected-error at +2{{use of undeclared identifier 'invalid'}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel async(invalid)
+
+  // 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 parallel async(4, 3)
+
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel async(returns_int())
+
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel async(5)
+
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel async(acc_async_sync)
 }
 
   // expected-warning at +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 07164b5e3379425..322080c3c35bcc9 100644
--- a/clang/test/ParserOpenACC/parse-clauses.cpp
+++ b/clang/test/ParserOpenACC/parse-clauses.cpp
@@ -17,6 +17,14 @@ void templ() {
   // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
 #pragma acc parallel vector_length(I)
   for(;;){}
+
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel async(T::value)
+  for(;;){}
+
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc parallel async(I)
+  for(;;){}
 }
 
 struct S {


        


More information about the cfe-commits mailing list