Author: erichkeane
Date: 2024-01-30T12:48:16-08:00
New Revision: 66ef6900f9f3aa4fab9f6e36af04f775948cdf9d

URL: 
https://github.com/llvm/llvm-project/commit/66ef6900f9f3aa4fab9f6e36af04f775948cdf9d
DIFF: 
https://github.com/llvm/llvm-project/commit/66ef6900f9f3aa4fab9f6e36af04f775948cdf9d.diff

LOG: [OpenACC] Better recover during clause parsing

Previously we gave up immediately and just escaped.  Instead, skip to
the next close paren and see if we can continue parsing the next clause
instead.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/Parse/ParseOpenACC.cpp 
b/clang/lib/Parse/ParseOpenACC.cpp
index bfe5061481ad9..1fee9f82b3e6a 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -784,29 +784,37 @@ bool 
Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
       ExprResult CondExpr = ParseOpenACCConditionalExpr(*this);
       // An invalid expression can be just about anything, so just give up on
       // this clause list.
-      if (CondExpr.isInvalid())
-        return true;
+      if (CondExpr.isInvalid()) {
+        Parens.skipToEnd();
+        return false;
+      }
       break;
     }
     case OpenACCClauseKind::CopyIn:
       tryParseAndConsumeSpecialTokenKind(
           *this, OpenACCSpecialTokenKind::ReadOnly, Kind);
-      if (ParseOpenACCClauseVarList(Kind))
-        return true;
+      if (ParseOpenACCClauseVarList(Kind)) {
+        Parens.skipToEnd();
+        return false;
+      }
       break;
     case OpenACCClauseKind::Create:
     case OpenACCClauseKind::CopyOut:
       tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Zero,
                                          Kind);
-      if (ParseOpenACCClauseVarList(Kind))
-        return true;
+      if (ParseOpenACCClauseVarList(Kind)) {
+        Parens.skipToEnd();
+        return false;
+      }
       break;
     case OpenACCClauseKind::Reduction:
       // If we're missing a clause-kind (or it is invalid), see if we can parse
       // the var-list anyway.
       ParseReductionOperator(*this);
-      if (ParseOpenACCClauseVarList(Kind))
-        return true;
+      if (ParseOpenACCClauseVarList(Kind)) {
+        Parens.skipToEnd();
+        return false;
+      }
       break;
     case OpenACCClauseKind::Self:
       // The 'self' clause is a var-list instead of a 'condition' in the case 
of
@@ -828,22 +836,28 @@ bool 
Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
     case OpenACCClauseKind::Present:
     case OpenACCClauseKind::Private:
     case OpenACCClauseKind::UseDevice:
-      if (ParseOpenACCClauseVarList(Kind))
-        return true;
+      if (ParseOpenACCClauseVarList(Kind)) {
+        Parens.skipToEnd();
+        return false;
+      }
       break;
     case OpenACCClauseKind::Collapse: {
       tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Force,
                                          Kind);
       ExprResult NumLoops =
           getActions().CorrectDelayedTyposInExpr(ParseConstantExpression());
-      if (NumLoops.isInvalid())
-        return true;
+      if (NumLoops.isInvalid()) {
+        Parens.skipToEnd();
+        return false;
+      }
       break;
     }
     case OpenACCClauseKind::Bind: {
       ExprResult BindArg = ParseOpenACCBindClauseArgument();
-      if (BindArg.isInvalid())
-        return true;
+      if (BindArg.isInvalid()) {
+        Parens.skipToEnd();
+        return false;
+      }
       break;
     }
     case OpenACCClauseKind::NumGangs:
@@ -852,8 +866,10 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind 
DirKind,
     case OpenACCClauseKind::DefaultAsync:
     case OpenACCClauseKind::VectorLength: {
       ExprResult IntExpr = ParseOpenACCIntExpr();
-      if (IntExpr.isInvalid())
-        return true;
+      if (IntExpr.isInvalid()) {
+        Parens.skipToEnd();
+        return false;
+      }
       break;
     }
     case OpenACCClauseKind::DType:
@@ -863,12 +879,15 @@ bool 
Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
         // device_type in Sema.
         ConsumeToken();
       } else if (ParseOpenACCDeviceTypeList()) {
-        return true;
+        Parens.skipToEnd();
+        return false;
       }
       break;
     case OpenACCClauseKind::Tile:
-      if (ParseOpenACCSizeExprList())
-        return true;
+      if (ParseOpenACCSizeExprList()) {
+        Parens.skipToEnd();
+        return false;
+      }
       break;
     default:
       llvm_unreachable("Not a required parens type?");
@@ -883,8 +902,10 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind 
DirKind,
         ExprResult CondExpr = ParseOpenACCConditionalExpr(*this);
         // An invalid expression can be just about anything, so just give up on
         // this clause list.
-        if (CondExpr.isInvalid())
-          return true;
+        if (CondExpr.isInvalid()) {
+          Parens.skipToEnd();
+          return false;
+        }
         break;
       }
       case OpenACCClauseKind::Vector:
@@ -895,19 +916,25 @@ bool 
Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
                                                : OpenACCSpecialTokenKind::Num,
                                            Kind);
         ExprResult IntExpr = ParseOpenACCIntExpr();
-        if (IntExpr.isInvalid())
-          return true;
+        if (IntExpr.isInvalid()) {
+          Parens.skipToEnd();
+          return false;
+        }
         break;
       }
       case OpenACCClauseKind::Async: {
         ExprResult AsyncArg = ParseOpenACCAsyncArgument();
-        if (AsyncArg.isInvalid())
-          return true;
+        if (AsyncArg.isInvalid()) {
+          Parens.skipToEnd();
+          return false;
+        }
         break;
       }
       case OpenACCClauseKind::Gang:
-        if (ParseOpenACCGangArgList())
-          return true;
+        if (ParseOpenACCGangArgList()) {
+          Parens.skipToEnd();
+          return false;
+        }
         break;
       case OpenACCClauseKind::Wait:
         if (ParseOpenACCWaitArgument()) {

diff  --git a/clang/test/ParserOpenACC/parse-clauses.c 
b/clang/test/ParserOpenACC/parse-clauses.c
index c7a8f4b23509c..18eb0fc996cce 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -205,18 +205,24 @@ void IfClause() {
 #pragma acc serial if, seq
   for(;;){}
 
-  // expected-error@+2{{expected expression}}
+  // 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 serial if(
   for(;;){}
 
-  // expected-error@+2{{use of undeclared identifier 'seq'}}
+  // expected-error@+4{{use of undeclared identifier 'seq'}}
+  // expected-error@+3{{expected ')'}}
+  // expected-note@+2{{to match this '('}}
   // expected-warning@+1{{OpenACC directives not yet implemented, pragma 
ignored}}
 #pragma acc serial if( seq
   for(;;){}
 
-  // expected-error@+3{{expected expression}}
-  // expected-error@+2{{use of undeclared identifier 'seq'}}
+  // expected-error@+5{{expected expression}}
+  // expected-error@+4{{use of undeclared identifier 'seq'}}
+  // expected-error@+3{{expected ')'}}
+  // expected-note@+2{{to match this '('}}
   // expected-warning@+1{{OpenACC directives not yet implemented, pragma 
ignored}}
 #pragma acc serial if(, seq
   for(;;){}
@@ -284,18 +290,24 @@ void SyncClause() {
 #pragma acc serial loop self, seq
   for(;;){}
 
-  // expected-error@+2{{expected expression}}
+  // 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 serial loop self(
   for(;;){}
 
-  // expected-error@+2{{use of undeclared identifier 'seq'}}
+  // expected-error@+4{{use of undeclared identifier 'seq'}}
+  // expected-error@+3{{expected ')'}}
+  // expected-note@+2{{to match this '('}}
   // expected-warning@+1{{OpenACC directives not yet implemented, pragma 
ignored}}
 #pragma acc serial loop self( seq
   for(;;){}
 
-  // expected-error@+3{{expected expression}}
-  // expected-error@+2{{use of undeclared identifier 'seq'}}
+  // expected-error@+5{{expected expression}}
+  // expected-error@+4{{use of undeclared identifier 'seq'}}
+  // expected-error@+3{{expected ')'}}
+  // expected-note@+2{{to match this '('}}
   // expected-warning@+1{{OpenACC directives not yet implemented, pragma 
ignored}}
 #pragma acc serial loop self(, seq
   for(;;){}
@@ -340,7 +352,9 @@ void SyncClause() {
 #pragma acc serial self(i > j
   for(;;){}
 
-  // expected-error@+2{{use of undeclared identifier 'seq'}}
+  // expected-error@+4{{use of undeclared identifier 'seq'}}
+  // expected-error@+3{{expected ')'}}
+  // expected-note@+2{{to match this '('}}
   // expected-warning@+1{{OpenACC directives not yet implemented, pragma 
ignored}}
 #pragma acc serial self(i > j, seq
   for(;;){}
@@ -405,11 +419,15 @@ void VarListClauses() {
   // expected-warning@+1{{OpenACC directives not yet implemented, pragma 
ignored}}
 #pragma acc serial copy), seq
 
-  // expected-error@+2{{expected expression}}
+  // 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 serial copy(
 
-  // expected-error@+2{{expected expression}}
+  // 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 serial copy(, seq
 


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to