Skip to content

Commit 1b75b9e

Browse files
committed
[OpenACC] Handle sema for gang, worker, vector, seq clauses on routine
These 4 clauses are mutually exclusive, AND require at least one of them. Additionally, gang has some additional restrictions in that only the 'dim' specifier is permitted. This patch implements all of this, and ends up refactoring the handling of each of these clauses for readabililty.
1 parent c9e250a commit 1b75b9e

16 files changed

+756
-461
lines changed

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,8 @@ class SemaOpenACC : public SemaBase {
698698
/// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
699699
/// happen before any associated declarations or statements have been parsed.
700700
/// This function is only called when we are parsing a 'Decl' context.
701-
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc);
701+
bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
702+
ArrayRef<const OpenACCClause *> Clauses);
702703
/// Called when we encounter an associated statement for our construct, this
703704
/// should check legality of the statement as it appertains to this Construct.
704705
StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc,

clang/lib/AST/DeclPrinter.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,9 +1918,12 @@ void DeclPrinter::VisitNonTypeTemplateParmDecl(
19181918

19191919
void DeclPrinter::VisitOpenACCDeclareDecl(OpenACCDeclareDecl *D) {
19201920
if (!D->isInvalidDecl()) {
1921-
Out << "#pragma acc declare ";
1922-
OpenACCClausePrinter Printer(Out, Policy);
1923-
Printer.VisitClauseList(D->clauses());
1921+
Out << "#pragma acc declare";
1922+
if (!D->clauses().empty()) {
1923+
Out << ' ';
1924+
OpenACCClausePrinter Printer(Out, Policy);
1925+
Printer.VisitClauseList(D->clauses());
1926+
}
19241927
}
19251928
}
19261929
void DeclPrinter::VisitOpenACCRoutineDecl(OpenACCRoutineDecl *D) {
@@ -1941,7 +1944,10 @@ void DeclPrinter::VisitOpenACCRoutineDecl(OpenACCRoutineDecl *D) {
19411944
Out << ")";
19421945
}
19431946

1944-
OpenACCClausePrinter Printer(Out, Policy);
1945-
Printer.VisitClauseList(D->clauses());
1947+
if (!D->clauses().empty()) {
1948+
Out << ' ';
1949+
OpenACCClausePrinter Printer(Out, Policy);
1950+
Printer.VisitClauseList(D->clauses());
1951+
}
19461952
}
19471953
}

clang/lib/Parse/ParseOpenACC.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,8 +1539,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() {
15391539

15401540
OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
15411541

1542-
if (getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind,
1543-
DirInfo.StartLoc))
1542+
if (getActions().OpenACC().ActOnStartDeclDirective(
1543+
DirInfo.DirKind, DirInfo.StartLoc, DirInfo.Clauses))
15441544
return nullptr;
15451545

15461546
return DeclGroupPtrTy::make(getActions().OpenACC().ActOnEndDeclDirective(

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,7 +1555,7 @@ bool SemaOpenACC::ActOnStartStmtDirective(
15551555
// Declaration directives an appear in a statement location, so call into that
15561556
// function here.
15571557
if (K == OpenACCDirectiveKind::Declare || K == OpenACCDirectiveKind::Routine)
1558-
return ActOnStartDeclDirective(K, StartLoc);
1558+
return ActOnStartDeclDirective(K, StartLoc, Clauses);
15591559

15601560
SemaRef.DiscardCleanupsInEvaluationContext();
15611561
SemaRef.PopExpressionEvaluationContext();
@@ -1832,14 +1832,29 @@ StmtResult SemaOpenACC::ActOnAssociatedStmt(
18321832
llvm_unreachable("Invalid associated statement application");
18331833
}
18341834

1835-
bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K,
1836-
SourceLocation StartLoc) {
1835+
bool SemaOpenACC::ActOnStartDeclDirective(
1836+
OpenACCDirectiveKind K, SourceLocation StartLoc,
1837+
ArrayRef<const OpenACCClause *> Clauses) {
18371838
// OpenCC3.3 2.1 (line 889)
18381839
// A program must not depend on the order of evaluation of expressions in
18391840
// clause arguments or on any side effects of the evaluations.
18401841
SemaRef.DiscardCleanupsInEvaluationContext();
18411842
SemaRef.PopExpressionEvaluationContext();
18421843

1844+
if (K == OpenACCDirectiveKind::Routine &&
1845+
llvm::find_if(Clauses,
1846+
llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,
1847+
OpenACCVectorClause, OpenACCSeqClause>) ==
1848+
Clauses.end())
1849+
return Diag(StartLoc, diag::err_acc_construct_one_clause_of)
1850+
<< K
1851+
<< GetListOfClauses({
1852+
OpenACCClauseKind::Gang,
1853+
OpenACCClauseKind::Worker,
1854+
OpenACCClauseKind::Vector,
1855+
OpenACCClauseKind::Seq,
1856+
});
1857+
18431858
return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
18441859
}
18451860

0 commit comments

Comments
 (0)