[clang] 87f67c2 - [OpenACC] Implement 'self' clause parsing

via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 8 12:10:19 PST 2024


Author: erichkeane
Date: 2024-01-08T12:10:13-08:00
New Revision: 87f67c2599410786ea3600d388fd1d2df13e60af

URL: https://github.com/llvm/llvm-project/commit/87f67c2599410786ea3600d388fd1d2df13e60af
DIFF: https://github.com/llvm/llvm-project/commit/87f67c2599410786ea3600d388fd1d2df13e60af.diff

LOG: [OpenACC] Implement 'self' clause parsing

The 'self' clause takes an optional 'condition' expression, same as the
non-optional expression taken by the 'if' clause.  This patch extracts
the 'condition' expression to a separate function, and implements the
'optional parens' infrastructure for clauses, then implements 'self'
parsing.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index f6a628db29cf48..b0c157e0023600 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -96,6 +96,8 @@ enum class OpenACCClauseKind {
   /// 'if' clause, allowed on all the Compute Constructs, Data Constructs,
   /// Executable Constructs, and Combined Constructs.
   If,
+  /// 'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
+  Self,
   /// Represents an invalid clause, for the purposes of parsing.
   Invalid,
 };

diff  --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 84e994ef00816d..c9224d3ae910cd 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -96,6 +96,7 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
       .Case("if_present", OpenACCClauseKind::IfPresent)
       .Case("independent", OpenACCClauseKind::Independent)
       .Case("nohost", OpenACCClauseKind::NoHost)
+      .Case("self", OpenACCClauseKind::Self)
       .Case("seq", OpenACCClauseKind::Seq)
       .Case("vector", OpenACCClauseKind::Vector)
       .Case("worker", OpenACCClauseKind::Worker)
@@ -328,10 +329,22 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
   return DirKind;
 }
 
+bool ClauseHasOptionalParens(OpenACCClauseKind Kind) {
+  return Kind == OpenACCClauseKind::Self;
+}
+
 bool ClauseHasRequiredParens(OpenACCClauseKind Kind) {
   return Kind == OpenACCClauseKind::Default || Kind == OpenACCClauseKind::If;
 }
 
+ExprResult ParseOpenACCConditionalExpr(Parser &P) {
+  // FIXME: It isn't clear if the spec saying 'condition' means the same as
+  // it does in an if/while/etc (See ParseCXXCondition), however as it was
+  // written with Fortran/C in mind, we're going to assume it just means an
+  // 'expression evaluating to boolean'.
+  return P.getActions().CorrectDelayedTyposInExpr(P.ParseExpression());
+}
+
 bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
   BalancedDelimiterTracker Parens(P, tok::l_paren,
                                   tok::annot_pragma_openacc_end);
@@ -362,12 +375,7 @@ bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
       break;
     }
     case OpenACCClauseKind::If: {
-      // FIXME: It isn't clear if the spec saying 'condition' means the same as
-      // it does in an if/while/etc (See ParseCXXCondition), however as it was
-      // written with Fortran/C in mind, we're going to assume it just means an
-      // 'expression evaluating to boolean'.
-      ExprResult CondExpr =
-          P.getActions().CorrectDelayedTyposInExpr(P.ParseExpression());
+      ExprResult CondExpr = ParseOpenACCConditionalExpr(P);
       // An invalid expression can be just about anything, so just give up on
       // this clause list.
       if (CondExpr.isInvalid())
@@ -379,8 +387,23 @@ bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
     }
 
     return Parens.consumeClose();
+  } else if (ClauseHasOptionalParens(Kind)) {
+    if (!Parens.consumeOpen()) {
+      switch (Kind) {
+      case OpenACCClauseKind::Self: {
+        ExprResult CondExpr = ParseOpenACCConditionalExpr(P);
+        // An invalid expression can be just about anything, so just give up on
+        // this clause list.
+        if (CondExpr.isInvalid())
+          return true;
+        break;
+      }
+      default:
+        llvm_unreachable("Not an optional parens type?");
+      }
+      Parens.consumeClose();
+    }
   }
-  // FIXME: Handle optional parens
   return false;
 }
 

diff  --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index b247210ff6c764..11e89d420e6b08 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -236,6 +236,85 @@ void IfClause() {
   for(;;){}
 }
 
+void SyncClause() {
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self
+  for(;;){}
+
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self, seq
+  for(;;){}
+
+  // expected-error at +2{{expected expression}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(
+  for(;;){}
+
+  // expected-error at +2{{use of undeclared identifier 'seq'}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self( seq
+  for(;;){}
+
+  // expected-error at +3{{expected expression}}
+  // expected-error at +2{{use of undeclared identifier 'seq'}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(, seq
+  for(;;){}
+
+  // expected-error at +2{{expected identifier}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self)
+  for(;;){}
+
+  // expected-error at +2{{expected identifier}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self) seq
+  for(;;){}
+
+  // expected-error at +2{{expected identifier}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self), seq
+  for(;;){}
+
+
+  // expected-error at +2{{expected expression}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(), seq
+  for(;;){}
+
+  // expected-error at +3{{expected expression}}
+  // expected-error at +2{{expected expression}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(,), seq
+  for(;;){}
+
+  // expected-error at +2{{use of undeclared identifier 'invalid_expr'}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop self(invalid_expr), seq
+  for(;;){}
+
+  int i, j;
+
+  // 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 serial self(i > j
+  for(;;){}
+
+  // expected-error at +2{{use of undeclared identifier 'seq'}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial self(i > j, seq
+  for(;;){}
+
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial self(i > j)
+  for(;;){}
+
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial self(1+5>3), seq
+  for(;;){}
+}
+
   // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
 #pragma acc routine worker, vector, seq, nohost
 void bar();


        


More information about the cfe-commits mailing list