Skip to content

Commit 9c4e7a1

Browse files
committed
[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.
1 parent d6ee91b commit 9c4e7a1

File tree

3 files changed

+54
-17
lines changed

3 files changed

+54
-17
lines changed

clang/include/clang/Parse/Parser.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3574,11 +3574,12 @@ class Parser : public CodeCompletionHandler {
35743574
bool ParseOpenACCClauseVarList(OpenACCClauseKind Kind);
35753575
/// Parses any parameters for an OpenACC Clause, including required/optional
35763576
/// parens.
3577-
bool ParseOpenACCClauseParams(OpenACCClauseKind Kind);
3577+
bool ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
3578+
OpenACCClauseKind Kind);
35783579
/// Parses a single clause in a clause-list for OpenACC.
3579-
bool ParseOpenACCClause();
3580+
bool ParseOpenACCClause(OpenACCDirectiveKind DirKind);
35803581
/// Parses the clause-list for an OpenACC directive.
3581-
void ParseOpenACCClauseList();
3582+
void ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
35823583
bool ParseOpenACCWaitArgument();
35833584

35843585
private:

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,12 @@ enum ClauseParensKind {
393393
Required
394394
};
395395

396-
ClauseParensKind getClauseParensKind(OpenACCClauseKind Kind) {
396+
ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind,
397+
OpenACCClauseKind Kind) {
397398
switch (Kind) {
398399
case OpenACCClauseKind::Self:
399-
return ClauseParensKind::Optional;
400+
return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required
401+
: ClauseParensKind::Optional;
400402

401403
case OpenACCClauseKind::Default:
402404
case OpenACCClauseKind::If:
@@ -433,12 +435,14 @@ ClauseParensKind getClauseParensKind(OpenACCClauseKind Kind) {
433435
llvm_unreachable("Unhandled clause kind");
434436
}
435437

436-
bool ClauseHasOptionalParens(OpenACCClauseKind Kind) {
437-
return getClauseParensKind(Kind) == ClauseParensKind::Optional;
438+
bool ClauseHasOptionalParens(OpenACCDirectiveKind DirKind,
439+
OpenACCClauseKind Kind) {
440+
return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Optional;
438441
}
439442

440-
bool ClauseHasRequiredParens(OpenACCClauseKind Kind) {
441-
return getClauseParensKind(Kind) == ClauseParensKind::Required;
443+
bool ClauseHasRequiredParens(OpenACCDirectiveKind DirKind,
444+
OpenACCClauseKind Kind) {
445+
return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Required;
442446
}
443447

444448
ExprResult ParseOpenACCConditionalExpr(Parser &P) {
@@ -465,7 +469,7 @@ void SkipUntilEndOfDirective(Parser &P) {
465469
// a pqr-list is a comma-separated list of pdr items. The one exception is a
466470
// clause-list, which is a list of one or more clauses optionally separated by
467471
// commas.
468-
void Parser::ParseOpenACCClauseList() {
472+
void Parser::ParseOpenACCClauseList(OpenACCDirectiveKind DirKind) {
469473
bool FirstClause = true;
470474
while (getCurToken().isNot(tok::annot_pragma_openacc_end)) {
471475
// Comma is optional in a clause-list.
@@ -475,7 +479,7 @@ void Parser::ParseOpenACCClauseList() {
475479

476480
// Recovering from a bad clause is really difficult, so we just give up on
477481
// error.
478-
if (ParseOpenACCClause()) {
482+
if (ParseOpenACCClause(DirKind)) {
479483
SkipUntilEndOfDirective(*this);
480484
return;
481485
}
@@ -508,7 +512,7 @@ bool Parser::ParseOpenACCClauseVarList(OpenACCClauseKind Kind) {
508512
// really have its owner grammar and each individual one has its own definition.
509513
// However, they all are named with a single-identifier (or auto/default!)
510514
// token, followed in some cases by either braces or parens.
511-
bool Parser::ParseOpenACCClause() {
515+
bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) {
512516
// A number of clause names are actually keywords, so accept a keyword that
513517
// can be converted to a name.
514518
if (expectIdentifierOrKeyword(*this))
@@ -523,14 +527,15 @@ bool Parser::ParseOpenACCClause() {
523527
// Consume the clause name.
524528
ConsumeToken();
525529

526-
return ParseOpenACCClauseParams(Kind);
530+
return ParseOpenACCClauseParams(DirKind, Kind);
527531
}
528532

529-
bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) {
533+
bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
534+
OpenACCClauseKind Kind) {
530535
BalancedDelimiterTracker Parens(*this, tok::l_paren,
531536
tok::annot_pragma_openacc_end);
532537

533-
if (ClauseHasRequiredParens(Kind)) {
538+
if (ClauseHasRequiredParens(DirKind, Kind)) {
534539
if (Parens.expectAndConsume()) {
535540
// We are missing a paren, so assume that the person just forgot the
536541
// parameter. Return 'false' so we try to continue on and parse the next
@@ -576,6 +581,12 @@ bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) {
576581
if (ParseOpenACCClauseVarList(Kind))
577582
return true;
578583
break;
584+
case OpenACCClauseKind::Self:
585+
// The 'self' clause is a var-list instead of a 'condition' in the case of
586+
// the 'update' clause, so we have to handle it here. U se an assert to
587+
// make sure we get the right differentiator.
588+
assert(DirKind == OpenACCDirectiveKind::Update);
589+
LLVM_FALLTHROUGH;
579590
case OpenACCClauseKind::Attach:
580591
case OpenACCClauseKind::Copy:
581592
case OpenACCClauseKind::Delete:
@@ -598,10 +609,11 @@ bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) {
598609
}
599610

600611
return Parens.consumeClose();
601-
} else if (ClauseHasOptionalParens(Kind)) {
612+
} else if (ClauseHasOptionalParens(DirKind, Kind)) {
602613
if (!Parens.consumeOpen()) {
603614
switch (Kind) {
604615
case OpenACCClauseKind::Self: {
616+
assert(DirKind != OpenACCDirectiveKind::Update);
605617
ExprResult CondExpr = ParseOpenACCConditionalExpr(*this);
606618
// An invalid expression can be just about anything, so just give up on
607619
// this clause list.
@@ -817,7 +829,7 @@ void Parser::ParseOpenACCDirective() {
817829
}
818830

819831
// Parses the list of clauses, if present.
820-
ParseOpenACCClauseList();
832+
ParseOpenACCClauseList(DirKind);
821833

822834
Diag(getCurToken(), diag::warn_pragma_acc_unimplemented);
823835
assert(Tok.is(tok::annot_pragma_openacc_end) &&

clang/test/ParserOpenACC/parse-clauses.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,11 @@ void SyncClause() {
306306
#pragma acc serial self(i > j, seq
307307
for(;;){}
308308

309+
// expected-warning@+2{{left operand of comma operator has no effect}}
310+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
311+
#pragma acc serial self(i, j)
312+
for(;;){}
313+
309314
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
310315
#pragma acc serial self(i > j)
311316
for(;;){}
@@ -323,6 +328,25 @@ struct HasMembersArray {
323328
struct Members MemArr[4];
324329
};
325330

331+
// On 'update', self behaves differently and requires parens, plus takes a var-list instead.
332+
void SelfUpdate() {
333+
struct Members s;
334+
335+
// expected-error@+2{{expected '('}}
336+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
337+
#pragma acc update self
338+
for(;;){}
339+
340+
// expected-error@+2{{use of undeclared identifier 'zero'}}
341+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
342+
#pragma acc update self(zero : s.array[s.value : 5], s.value), seq
343+
for(;;){}
344+
345+
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
346+
#pragma acc update self(s.array[s.value : 5], s.value), seq
347+
for(;;){}
348+
}
349+
326350
void VarListClauses() {
327351
// expected-error@+2{{expected '('}}
328352
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}

0 commit comments

Comments
 (0)