[clang] 9c4e7a1 - [OpenACC] Implement 'self' clause parsing on 'update'.

via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 16 09:25:39 PST 2024


Author: erichkeane
Date: 2024-01-16T09:25:34-08:00
New Revision: 9c4e7a159b1f2228ddf146c58c2478418cd63e86

URL: https://github.com/llvm/llvm-project/commit/9c4e7a159b1f2228ddf146c58c2478418cd63e86
DIFF: https://github.com/llvm/llvm-project/commit/9c4e7a159b1f2228ddf146c58c2478418cd63e86.diff

LOG: [OpenACC] Implement 'self' clause parsing on 'update'.

The update directive has its own version of 'self' that has a 'var-list'
instead of a 'condition' (like the serial/parallel/kernel/combined
constructs).  This patch special cases it on 'update' to make sure we
parse this correctly.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index e50a4d05b459918..fc56de823d7efaf 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3574,11 +3574,12 @@ class Parser : public CodeCompletionHandler {
   bool ParseOpenACCClauseVarList(OpenACCClauseKind Kind);
   /// Parses any parameters for an OpenACC Clause, including required/optional
   /// parens.
-  bool ParseOpenACCClauseParams(OpenACCClauseKind Kind);
+  bool ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
+                                OpenACCClauseKind Kind);
   /// Parses a single clause in a clause-list for OpenACC.
-  bool ParseOpenACCClause();
+  bool ParseOpenACCClause(OpenACCDirectiveKind DirKind);
   /// Parses the clause-list for an OpenACC directive.
-  void ParseOpenACCClauseList();
+  void ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
   bool ParseOpenACCWaitArgument();
 
 private:

diff  --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index d34cc5f799c9553..5196eb9056be281 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -393,10 +393,12 @@ enum ClauseParensKind {
   Required
 };
 
-ClauseParensKind getClauseParensKind(OpenACCClauseKind Kind) {
+ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind,
+                                     OpenACCClauseKind Kind) {
   switch (Kind) {
   case OpenACCClauseKind::Self:
-    return ClauseParensKind::Optional;
+    return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required
+                                                   : ClauseParensKind::Optional;
 
   case OpenACCClauseKind::Default:
   case OpenACCClauseKind::If:
@@ -433,12 +435,14 @@ ClauseParensKind getClauseParensKind(OpenACCClauseKind Kind) {
   llvm_unreachable("Unhandled clause kind");
 }
 
-bool ClauseHasOptionalParens(OpenACCClauseKind Kind) {
-  return getClauseParensKind(Kind) == ClauseParensKind::Optional;
+bool ClauseHasOptionalParens(OpenACCDirectiveKind DirKind,
+                             OpenACCClauseKind Kind) {
+  return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Optional;
 }
 
-bool ClauseHasRequiredParens(OpenACCClauseKind Kind) {
-  return getClauseParensKind(Kind) == ClauseParensKind::Required;
+bool ClauseHasRequiredParens(OpenACCDirectiveKind DirKind,
+                             OpenACCClauseKind Kind) {
+  return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Required;
 }
 
 ExprResult ParseOpenACCConditionalExpr(Parser &P) {
@@ -465,7 +469,7 @@ void SkipUntilEndOfDirective(Parser &P) {
 // a pqr-list is a comma-separated list of pdr items. The one exception is a
 // clause-list, which is a list of one or more clauses optionally separated by
 // commas.
-void Parser::ParseOpenACCClauseList() {
+void Parser::ParseOpenACCClauseList(OpenACCDirectiveKind DirKind) {
   bool FirstClause = true;
   while (getCurToken().isNot(tok::annot_pragma_openacc_end)) {
     // Comma is optional in a clause-list.
@@ -475,7 +479,7 @@ void Parser::ParseOpenACCClauseList() {
 
     // Recovering from a bad clause is really 
diff icult, so we just give up on
     // error.
-    if (ParseOpenACCClause()) {
+    if (ParseOpenACCClause(DirKind)) {
       SkipUntilEndOfDirective(*this);
       return;
     }
@@ -508,7 +512,7 @@ bool Parser::ParseOpenACCClauseVarList(OpenACCClauseKind Kind) {
 // really have its owner grammar and each individual one has its own definition.
 // However, they all are named with a single-identifier (or auto/default!)
 // token, followed in some cases by either braces or parens.
-bool Parser::ParseOpenACCClause() {
+bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) {
   // A number of clause names are actually keywords, so accept a keyword that
   // can be converted to a name.
   if (expectIdentifierOrKeyword(*this))
@@ -523,14 +527,15 @@ bool Parser::ParseOpenACCClause() {
   // Consume the clause name.
   ConsumeToken();
 
-  return ParseOpenACCClauseParams(Kind);
+  return ParseOpenACCClauseParams(DirKind, Kind);
 }
 
-bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) {
+bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
+                                      OpenACCClauseKind Kind) {
   BalancedDelimiterTracker Parens(*this, tok::l_paren,
                                   tok::annot_pragma_openacc_end);
 
-  if (ClauseHasRequiredParens(Kind)) {
+  if (ClauseHasRequiredParens(DirKind, Kind)) {
     if (Parens.expectAndConsume()) {
       // We are missing a paren, so assume that the person just forgot the
       // parameter.  Return 'false' so we try to continue on and parse the next
@@ -576,6 +581,12 @@ bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) {
       if (ParseOpenACCClauseVarList(Kind))
         return true;
       break;
+    case OpenACCClauseKind::Self:
+      // The 'self' clause is a var-list instead of a 'condition' in the case of
+      // the 'update' clause, so we have to handle it here.  U se an assert to
+      // make sure we get the right 
diff erentiator.
+      assert(DirKind == OpenACCDirectiveKind::Update);
+      LLVM_FALLTHROUGH;
     case OpenACCClauseKind::Attach:
     case OpenACCClauseKind::Copy:
     case OpenACCClauseKind::Delete:
@@ -598,10 +609,11 @@ bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) {
     }
 
     return Parens.consumeClose();
-  } else if (ClauseHasOptionalParens(Kind)) {
+  } else if (ClauseHasOptionalParens(DirKind, Kind)) {
     if (!Parens.consumeOpen()) {
       switch (Kind) {
       case OpenACCClauseKind::Self: {
+        assert(DirKind != OpenACCDirectiveKind::Update);
         ExprResult CondExpr = ParseOpenACCConditionalExpr(*this);
         // An invalid expression can be just about anything, so just give up on
         // this clause list.
@@ -817,7 +829,7 @@ void Parser::ParseOpenACCDirective() {
   }
 
   // Parses the list of clauses, if present.
-  ParseOpenACCClauseList();
+  ParseOpenACCClauseList(DirKind);
 
   Diag(getCurToken(), diag::warn_pragma_acc_unimplemented);
   assert(Tok.is(tok::annot_pragma_openacc_end) &&

diff  --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index 5cbcf5410845c61..c5638531b68b965 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -306,6 +306,11 @@ void SyncClause() {
 #pragma acc serial self(i > j, seq
   for(;;){}
 
+  // expected-warning at +2{{left operand of comma operator has no effect}}
+  // 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(i > j)
   for(;;){}
@@ -323,6 +328,25 @@ struct HasMembersArray {
   struct Members MemArr[4];
 };
 
+// On 'update', self behaves 
diff erently and requires parens, plus takes a var-list instead.
+void SelfUpdate() {
+  struct Members s;
+
+  // expected-error at +2{{expected '('}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc update self
+  for(;;){}
+
+  // expected-error at +2{{use of undeclared identifier 'zero'}}
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc update self(zero : s.array[s.value : 5], s.value), seq
+  for(;;){}
+
+  // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc update self(s.array[s.value : 5], s.value), seq
+  for(;;){}
+}
+
 void VarListClauses() {
   // expected-error at +2{{expected '('}}
   // expected-warning at +1{{OpenACC directives not yet implemented, pragma ignored}}


        


More information about the cfe-commits mailing list