Skip to content

Commit 66ef690

Browse files
committed
[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.
1 parent 0dd0cbd commit 66ef690

File tree

2 files changed

+83
-38
lines changed

2 files changed

+83
-38
lines changed

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -784,29 +784,37 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
784784
ExprResult CondExpr = ParseOpenACCConditionalExpr(*this);
785785
// An invalid expression can be just about anything, so just give up on
786786
// this clause list.
787-
if (CondExpr.isInvalid())
788-
return true;
787+
if (CondExpr.isInvalid()) {
788+
Parens.skipToEnd();
789+
return false;
790+
}
789791
break;
790792
}
791793
case OpenACCClauseKind::CopyIn:
792794
tryParseAndConsumeSpecialTokenKind(
793795
*this, OpenACCSpecialTokenKind::ReadOnly, Kind);
794-
if (ParseOpenACCClauseVarList(Kind))
795-
return true;
796+
if (ParseOpenACCClauseVarList(Kind)) {
797+
Parens.skipToEnd();
798+
return false;
799+
}
796800
break;
797801
case OpenACCClauseKind::Create:
798802
case OpenACCClauseKind::CopyOut:
799803
tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Zero,
800804
Kind);
801-
if (ParseOpenACCClauseVarList(Kind))
802-
return true;
805+
if (ParseOpenACCClauseVarList(Kind)) {
806+
Parens.skipToEnd();
807+
return false;
808+
}
803809
break;
804810
case OpenACCClauseKind::Reduction:
805811
// If we're missing a clause-kind (or it is invalid), see if we can parse
806812
// the var-list anyway.
807813
ParseReductionOperator(*this);
808-
if (ParseOpenACCClauseVarList(Kind))
809-
return true;
814+
if (ParseOpenACCClauseVarList(Kind)) {
815+
Parens.skipToEnd();
816+
return false;
817+
}
810818
break;
811819
case OpenACCClauseKind::Self:
812820
// The 'self' clause is a var-list instead of a 'condition' in the case of
@@ -828,22 +836,28 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
828836
case OpenACCClauseKind::Present:
829837
case OpenACCClauseKind::Private:
830838
case OpenACCClauseKind::UseDevice:
831-
if (ParseOpenACCClauseVarList(Kind))
832-
return true;
839+
if (ParseOpenACCClauseVarList(Kind)) {
840+
Parens.skipToEnd();
841+
return false;
842+
}
833843
break;
834844
case OpenACCClauseKind::Collapse: {
835845
tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Force,
836846
Kind);
837847
ExprResult NumLoops =
838848
getActions().CorrectDelayedTyposInExpr(ParseConstantExpression());
839-
if (NumLoops.isInvalid())
840-
return true;
849+
if (NumLoops.isInvalid()) {
850+
Parens.skipToEnd();
851+
return false;
852+
}
841853
break;
842854
}
843855
case OpenACCClauseKind::Bind: {
844856
ExprResult BindArg = ParseOpenACCBindClauseArgument();
845-
if (BindArg.isInvalid())
846-
return true;
857+
if (BindArg.isInvalid()) {
858+
Parens.skipToEnd();
859+
return false;
860+
}
847861
break;
848862
}
849863
case OpenACCClauseKind::NumGangs:
@@ -852,8 +866,10 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
852866
case OpenACCClauseKind::DefaultAsync:
853867
case OpenACCClauseKind::VectorLength: {
854868
ExprResult IntExpr = ParseOpenACCIntExpr();
855-
if (IntExpr.isInvalid())
856-
return true;
869+
if (IntExpr.isInvalid()) {
870+
Parens.skipToEnd();
871+
return false;
872+
}
857873
break;
858874
}
859875
case OpenACCClauseKind::DType:
@@ -863,12 +879,15 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
863879
// device_type in Sema.
864880
ConsumeToken();
865881
} else if (ParseOpenACCDeviceTypeList()) {
866-
return true;
882+
Parens.skipToEnd();
883+
return false;
867884
}
868885
break;
869886
case OpenACCClauseKind::Tile:
870-
if (ParseOpenACCSizeExprList())
871-
return true;
887+
if (ParseOpenACCSizeExprList()) {
888+
Parens.skipToEnd();
889+
return false;
890+
}
872891
break;
873892
default:
874893
llvm_unreachable("Not a required parens type?");
@@ -883,8 +902,10 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
883902
ExprResult CondExpr = ParseOpenACCConditionalExpr(*this);
884903
// An invalid expression can be just about anything, so just give up on
885904
// this clause list.
886-
if (CondExpr.isInvalid())
887-
return true;
905+
if (CondExpr.isInvalid()) {
906+
Parens.skipToEnd();
907+
return false;
908+
}
888909
break;
889910
}
890911
case OpenACCClauseKind::Vector:
@@ -895,19 +916,25 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
895916
: OpenACCSpecialTokenKind::Num,
896917
Kind);
897918
ExprResult IntExpr = ParseOpenACCIntExpr();
898-
if (IntExpr.isInvalid())
899-
return true;
919+
if (IntExpr.isInvalid()) {
920+
Parens.skipToEnd();
921+
return false;
922+
}
900923
break;
901924
}
902925
case OpenACCClauseKind::Async: {
903926
ExprResult AsyncArg = ParseOpenACCAsyncArgument();
904-
if (AsyncArg.isInvalid())
905-
return true;
927+
if (AsyncArg.isInvalid()) {
928+
Parens.skipToEnd();
929+
return false;
930+
}
906931
break;
907932
}
908933
case OpenACCClauseKind::Gang:
909-
if (ParseOpenACCGangArgList())
910-
return true;
934+
if (ParseOpenACCGangArgList()) {
935+
Parens.skipToEnd();
936+
return false;
937+
}
911938
break;
912939
case OpenACCClauseKind::Wait:
913940
if (ParseOpenACCWaitArgument()) {

clang/test/ParserOpenACC/parse-clauses.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,18 +205,24 @@ void IfClause() {
205205
#pragma acc serial if, seq
206206
for(;;){}
207207

208-
// expected-error@+2{{expected expression}}
208+
// expected-error@+4{{expected expression}}
209+
// expected-error@+3{{expected ')'}}
210+
// expected-note@+2{{to match this '('}}
209211
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
210212
#pragma acc serial if(
211213
for(;;){}
212214

213-
// expected-error@+2{{use of undeclared identifier 'seq'}}
215+
// expected-error@+4{{use of undeclared identifier 'seq'}}
216+
// expected-error@+3{{expected ')'}}
217+
// expected-note@+2{{to match this '('}}
214218
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
215219
#pragma acc serial if( seq
216220
for(;;){}
217221

218-
// expected-error@+3{{expected expression}}
219-
// expected-error@+2{{use of undeclared identifier 'seq'}}
222+
// expected-error@+5{{expected expression}}
223+
// expected-error@+4{{use of undeclared identifier 'seq'}}
224+
// expected-error@+3{{expected ')'}}
225+
// expected-note@+2{{to match this '('}}
220226
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
221227
#pragma acc serial if(, seq
222228
for(;;){}
@@ -284,18 +290,24 @@ void SyncClause() {
284290
#pragma acc serial loop self, seq
285291
for(;;){}
286292

287-
// expected-error@+2{{expected expression}}
293+
// expected-error@+4{{expected expression}}
294+
// expected-error@+3{{expected ')'}}
295+
// expected-note@+2{{to match this '('}}
288296
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
289297
#pragma acc serial loop self(
290298
for(;;){}
291299

292-
// expected-error@+2{{use of undeclared identifier 'seq'}}
300+
// expected-error@+4{{use of undeclared identifier 'seq'}}
301+
// expected-error@+3{{expected ')'}}
302+
// expected-note@+2{{to match this '('}}
293303
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
294304
#pragma acc serial loop self( seq
295305
for(;;){}
296306

297-
// expected-error@+3{{expected expression}}
298-
// expected-error@+2{{use of undeclared identifier 'seq'}}
307+
// expected-error@+5{{expected expression}}
308+
// expected-error@+4{{use of undeclared identifier 'seq'}}
309+
// expected-error@+3{{expected ')'}}
310+
// expected-note@+2{{to match this '('}}
299311
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
300312
#pragma acc serial loop self(, seq
301313
for(;;){}
@@ -340,7 +352,9 @@ void SyncClause() {
340352
#pragma acc serial self(i > j
341353
for(;;){}
342354

343-
// expected-error@+2{{use of undeclared identifier 'seq'}}
355+
// expected-error@+4{{use of undeclared identifier 'seq'}}
356+
// expected-error@+3{{expected ')'}}
357+
// expected-note@+2{{to match this '('}}
344358
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
345359
#pragma acc serial self(i > j, seq
346360
for(;;){}
@@ -405,11 +419,15 @@ void VarListClauses() {
405419
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
406420
#pragma acc serial copy), seq
407421

408-
// expected-error@+2{{expected expression}}
422+
// expected-error@+4{{expected expression}}
423+
// expected-error@+3{{expected ')'}}
424+
// expected-note@+2{{to match this '('}}
409425
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
410426
#pragma acc serial copy(
411427

412-
// expected-error@+2{{expected expression}}
428+
// expected-error@+4{{expected expression}}
429+
// expected-error@+3{{expected ')'}}
430+
// expected-note@+2{{to match this '('}}
413431
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
414432
#pragma acc serial copy(, seq
415433

0 commit comments

Comments
 (0)