From 66ef6900f9f3aa4fab9f6e36af04f775948cdf9d Mon Sep 17 00:00:00 2001 From: erichkeane Date: Tue, 30 Jan 2024 08:40:19 -0800 Subject: [PATCH] [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. --- clang/lib/Parse/ParseOpenACC.cpp | 81 ++++++++++++++++-------- clang/test/ParserOpenACC/parse-clauses.c | 40 ++++++++---- 2 files changed, 83 insertions(+), 38 deletions(-) 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