[clang] bd909d2 - [OpenACC] Implement no_create and present clauses on compute constructs
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 3 06:52:00 PDT 2024
Author: erichkeane
Date: 2024-05-03T06:51:54-07:00
New Revision: bd909d2e6f2692685664c3f3b4db6047b2fb9441
URL: https://github.com/llvm/llvm-project/commit/bd909d2e6f2692685664c3f3b4db6047b2fb9441
DIFF: https://github.com/llvm/llvm-project/commit/bd909d2e6f2692685664c3f3b4db6047b2fb9441.diff
LOG: [OpenACC] Implement no_create and present clauses on compute constructs
These two are, from a semantic checking perspective, identical to
first-private/private/etc, other than appertainment. This patch
implements both.
Added:
clang/test/SemaOpenACC/compute-construct-no_create-clause.c
clang/test/SemaOpenACC/compute-construct-no_create-clause.cpp
clang/test/SemaOpenACC/compute-construct-present-clause.c
clang/test/SemaOpenACC/compute-construct-present-clause.cpp
Modified:
clang/include/clang/AST/OpenACCClause.h
clang/include/clang/Basic/OpenACCClauses.def
clang/include/clang/Sema/SemaOpenACC.h
clang/lib/AST/OpenACCClause.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Parse/ParseOpenACC.cpp
clang/lib/Sema/SemaOpenACC.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/AST/ast-print-openacc-compute-construct.cpp
clang/test/ParserOpenACC/parse-clauses.c
clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
clang/tools/libclang/CIndex.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h
index df290d06efd203..369129a35d8128 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -313,6 +313,44 @@ class OpenACCFirstPrivateClause final
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
};
+class OpenACCNoCreateClause final
+ : public OpenACCClauseWithVarList,
+ public llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> {
+
+ OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc)
+ : OpenACCClauseWithVarList(OpenACCClauseKind::NoCreate, BeginLoc,
+ LParenLoc, EndLoc) {
+ std::uninitialized_copy(VarList.begin(), VarList.end(),
+ getTrailingObjects<Expr *>());
+ setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
+ }
+
+public:
+ static OpenACCNoCreateClause *
+ Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+};
+
+class OpenACCPresentClause final
+ : public OpenACCClauseWithVarList,
+ public llvm::TrailingObjects<OpenACCPresentClause, Expr *> {
+
+ OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc)
+ : OpenACCClauseWithVarList(OpenACCClauseKind::Present, BeginLoc,
+ LParenLoc, EndLoc) {
+ std::uninitialized_copy(VarList.begin(), VarList.end(),
+ getTrailingObjects<Expr *>());
+ setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
+ }
+
+public:
+ static OpenACCPresentClause *
+ Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+};
+
template <class Impl> class OpenACCClauseVisitor {
Impl &getDerived() { return static_cast<Impl &>(*this); }
diff --git a/clang/include/clang/Basic/OpenACCClauses.def b/clang/include/clang/Basic/OpenACCClauses.def
index 884f0297aa50e0..d5f14d8646a4be 100644
--- a/clang/include/clang/Basic/OpenACCClauses.def
+++ b/clang/include/clang/Basic/OpenACCClauses.def
@@ -18,8 +18,10 @@
VISIT_CLAUSE(Default)
VISIT_CLAUSE(FirstPrivate)
VISIT_CLAUSE(If)
+VISIT_CLAUSE(NoCreate)
VISIT_CLAUSE(NumGangs)
VISIT_CLAUSE(NumWorkers)
+VISIT_CLAUSE(Present)
VISIT_CLAUSE(Private)
VISIT_CLAUSE(Self)
VISIT_CLAUSE(VectorLength)
diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
index a25c5244d9607a..cd91847a9591e1 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -118,6 +118,8 @@ class SemaOpenACC : public SemaBase {
ArrayRef<Expr *> getVarList() {
assert((ClauseKind == OpenACCClauseKind::Private ||
+ ClauseKind == OpenACCClauseKind::NoCreate ||
+ ClauseKind == OpenACCClauseKind::Present ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
return std::get<VarListDetails>(Details).VarList;
@@ -167,6 +169,8 @@ class SemaOpenACC : public SemaBase {
void setVarListDetails(ArrayRef<Expr *> VarList) {
assert((ClauseKind == OpenACCClauseKind::Private ||
+ ClauseKind == OpenACCClauseKind::NoCreate ||
+ ClauseKind == OpenACCClauseKind::Present ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
Details = VarListDetails{{VarList.begin(), VarList.end()}};
@@ -174,6 +178,8 @@ class SemaOpenACC : public SemaBase {
void setVarListDetails(llvm::SmallVector<Expr *> &&VarList) {
assert((ClauseKind == OpenACCClauseKind::Private ||
+ ClauseKind == OpenACCClauseKind::NoCreate ||
+ ClauseKind == OpenACCClauseKind::Present ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
Details = VarListDetails{std::move(VarList)};
diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp
index fdb802c8d2a66f..88fcb9a84f1f0b 100644
--- a/clang/lib/AST/OpenACCClause.cpp
+++ b/clang/lib/AST/OpenACCClause.cpp
@@ -153,6 +153,26 @@ OpenACCFirstPrivateClause *OpenACCFirstPrivateClause::Create(
OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc);
}
+OpenACCNoCreateClause *OpenACCNoCreateClause::Create(const ASTContext &C,
+ SourceLocation BeginLoc,
+ SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList,
+ SourceLocation EndLoc) {
+ void *Mem = C.Allocate(
+ OpenACCNoCreateClause::totalSizeToAlloc<Expr *>(VarList.size()));
+ return new (Mem) OpenACCNoCreateClause(BeginLoc, LParenLoc, VarList, EndLoc);
+}
+
+OpenACCPresentClause *OpenACCPresentClause::Create(const ASTContext &C,
+ SourceLocation BeginLoc,
+ SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList,
+ SourceLocation EndLoc) {
+ void *Mem = C.Allocate(
+ OpenACCPresentClause::totalSizeToAlloc<Expr *>(VarList.size()));
+ return new (Mem) OpenACCPresentClause(BeginLoc, LParenLoc, VarList, EndLoc);
+}
+
//===----------------------------------------------------------------------===//
// OpenACC clauses printing methods
//===----------------------------------------------------------------------===//
@@ -215,3 +235,17 @@ void OpenACCClausePrinter::VisitFirstPrivateClause(
[&](const Expr *E) { printExpr(E); });
OS << ")";
}
+
+void OpenACCClausePrinter::VisitNoCreateClause(const OpenACCNoCreateClause &C) {
+ OS << "no_create(";
+ llvm::interleaveComma(C.getVarList(), OS,
+ [&](const Expr *E) { printExpr(E); });
+ OS << ")";
+}
+
+void OpenACCClausePrinter::VisitPresentClause(const OpenACCPresentClause &C) {
+ OS << "present(";
+ llvm::interleaveComma(C.getVarList(), OS,
+ [&](const Expr *E) { printExpr(E); });
+ OS << ")";
+}
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 352bef47b39e45..b4ca81f5e25f16 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2521,6 +2521,18 @@ void OpenACCClauseProfiler::VisitFirstPrivateClause(
Profiler.VisitStmt(E);
}
+void OpenACCClauseProfiler::VisitNoCreateClause(
+ const OpenACCNoCreateClause &Clause) {
+ for (auto *E : Clause.getVarList())
+ Profiler.VisitStmt(E);
+}
+
+void OpenACCClauseProfiler::VisitPresentClause(
+ const OpenACCPresentClause &Clause) {
+ for (auto *E : Clause.getVarList())
+ Profiler.VisitStmt(E);
+}
+
void OpenACCClauseProfiler::VisitVectorLengthClause(
const OpenACCVectorLengthClause &Clause) {
assert(Clause.hasIntExpr() &&
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index a2cd5040230060..7d3ea76fbd61c6 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -399,8 +399,10 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
break;
case OpenACCClauseKind::If:
case OpenACCClauseKind::FirstPrivate:
+ case OpenACCClauseKind::NoCreate:
case OpenACCClauseKind::NumGangs:
case OpenACCClauseKind::NumWorkers:
+ case OpenACCClauseKind::Present:
case OpenACCClauseKind::Private:
case OpenACCClauseKind::Self:
case OpenACCClauseKind::VectorLength:
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 8784acc9a2f37f..a1074abd82faa3 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -928,12 +928,12 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
case OpenACCClauseKind::DevicePtr:
case OpenACCClauseKind::Host:
case OpenACCClauseKind::Link:
- case OpenACCClauseKind::NoCreate:
- case OpenACCClauseKind::Present:
case OpenACCClauseKind::UseDevice:
ParseOpenACCVarList();
break;
case OpenACCClauseKind::FirstPrivate:
+ case OpenACCClauseKind::NoCreate:
+ case OpenACCClauseKind::Present:
case OpenACCClauseKind::Private:
ParsedClause.setVarListDetails(ParseOpenACCVarList());
break;
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 778e09e7ce0080..3572d8f1090016 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -126,6 +126,33 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
default:
return false;
}
+ case OpenACCClauseKind::NoCreate:
+ switch (DirectiveKind) {
+ case OpenACCDirectiveKind::Parallel:
+ case OpenACCDirectiveKind::Serial:
+ case OpenACCDirectiveKind::Kernels:
+ case OpenACCDirectiveKind::Data:
+ case OpenACCDirectiveKind::ParallelLoop:
+ case OpenACCDirectiveKind::SerialLoop:
+ case OpenACCDirectiveKind::KernelsLoop:
+ return true;
+ default:
+ return false;
+ }
+ case OpenACCClauseKind::Present:
+ switch (DirectiveKind) {
+ case OpenACCDirectiveKind::Parallel:
+ case OpenACCDirectiveKind::Serial:
+ case OpenACCDirectiveKind::Kernels:
+ case OpenACCDirectiveKind::Data:
+ case OpenACCDirectiveKind::Declare:
+ case OpenACCDirectiveKind::ParallelLoop:
+ case OpenACCDirectiveKind::SerialLoop:
+ case OpenACCDirectiveKind::KernelsLoop:
+ return true;
+ default:
+ return false;
+ }
default:
// Do nothing so we can go to the 'unimplemented' diagnostic instead.
return true;
@@ -356,6 +383,36 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
Clause.getVarList(), Clause.getEndLoc());
}
+ case OpenACCClauseKind::NoCreate: {
+ // Restrictions only properly implemented on 'compute' constructs, and
+ // 'compute' constructs are the only construct that can do anything with
+ // this yet, so skip/treat as unimplemented in this case.
+ if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
+ break;
+
+ // ActOnVar ensured that everything is a valid variable reference, so there
+ // really isn't anything to do here. GCC does some duplicate-finding, though
+ // it isn't apparent in the standard where this is justified.
+
+ return OpenACCNoCreateClause::Create(
+ getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
+ Clause.getVarList(), Clause.getEndLoc());
+ }
+ case OpenACCClauseKind::Present: {
+ // Restrictions only properly implemented on 'compute' constructs, and
+ // 'compute' constructs are the only construct that can do anything with
+ // this yet, so skip/treat as unimplemented in this case.
+ if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
+ break;
+
+ // ActOnVar ensured that everything is a valid variable reference, so there
+ // really isn't anything to do here. GCC does some duplicate-finding, though
+ // it isn't apparent in the standard where this is justified.
+
+ return OpenACCPresentClause::Create(
+ getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
+ Clause.getVarList(), Clause.getEndLoc());
+ }
default:
break;
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 6ed5d62b7dbd7b..91945fcf2d7faf 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -11242,6 +11242,28 @@ void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
ParsedClause.getEndLoc());
}
+template <typename Derived>
+void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
+ const OpenACCNoCreateClause &C) {
+ ParsedClause.setVarListDetails(VisitVarList(C.getVarList()));
+
+ NewClause = OpenACCNoCreateClause::Create(
+ Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
+ ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
+ ParsedClause.getEndLoc());
+}
+
+template <typename Derived>
+void OpenACCClauseTransform<Derived>::VisitPresentClause(
+ const OpenACCPresentClause &C) {
+ ParsedClause.setVarListDetails(VisitVarList(C.getVarList()));
+
+ NewClause = OpenACCPresentClause::Create(
+ Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
+ ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
+ ParsedClause.getEndLoc());
+}
+
template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
const OpenACCNumWorkersClause &C) {
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index e80ea77f568d12..ca10bda18f1724 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11841,6 +11841,18 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
return OpenACCFirstPrivateClause::Create(getContext(), BeginLoc, LParenLoc,
VarList, EndLoc);
}
+ case OpenACCClauseKind::NoCreate: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCNoCreateClause::Create(getContext(), BeginLoc, LParenLoc,
+ VarList, EndLoc);
+ }
+ case OpenACCClauseKind::Present: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCPresentClause::Create(getContext(), BeginLoc, LParenLoc,
+ VarList, EndLoc);
+ }
case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Seq:
@@ -11859,8 +11871,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
case OpenACCClauseKind::DeviceResident:
case OpenACCClauseKind::Host:
case OpenACCClauseKind::Link:
- case OpenACCClauseKind::NoCreate:
- case OpenACCClauseKind::Present:
case OpenACCClauseKind::CopyOut:
case OpenACCClauseKind::CopyIn:
case OpenACCClauseKind::Create:
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index df53a1e4f2e1b7..e9698c28dcc9f2 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -7793,6 +7793,18 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
writeOpenACCVarList(FPC);
return;
}
+ case OpenACCClauseKind::NoCreate: {
+ const auto *NCC = cast<OpenACCNoCreateClause>(C);
+ writeSourceLocation(NCC->getLParenLoc());
+ writeOpenACCVarList(NCC);
+ return;
+ }
+ case OpenACCClauseKind::Present: {
+ const auto *PC = cast<OpenACCPresentClause>(C);
+ writeSourceLocation(PC->getLParenLoc());
+ writeOpenACCVarList(PC);
+ return;
+ }
case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Seq:
@@ -7811,8 +7823,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
case OpenACCClauseKind::DeviceResident:
case OpenACCClauseKind::Host:
case OpenACCClauseKind::Link:
- case OpenACCClauseKind::NoCreate:
- case OpenACCClauseKind::Present:
case OpenACCClauseKind::CopyOut:
case OpenACCClauseKind::CopyIn:
case OpenACCClauseKind::Create:
diff --git a/clang/test/AST/ast-print-openacc-compute-construct.cpp b/clang/test/AST/ast-print-openacc-compute-construct.cpp
index 993f4950217b5e..895660ae1641cf 100644
--- a/clang/test/AST/ast-print-openacc-compute-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-compute-construct.cpp
@@ -42,5 +42,16 @@ void foo() {
// CHECK: #pragma acc parallel firstprivate(i, array[1], array, array[1:2])
#pragma acc parallel firstprivate(i, array[1], array, array[1:2])
while(true);
+
+// CHECK: #pragma acc parallel no_create(i, array[1], array, array[1:2])
+#pragma acc parallel no_create(i, array[1], array, array[1:2])
+ while(true);
+
+// CHECK: #pragma acc parallel present(i, array[1], array, array[1:2])
+#pragma acc parallel present(i, array[1], array, array[1:2])
+ while(true);
+// CHECK: #pragma acc parallel no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2])
+#pragma acc parallel no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2])
+ while(true);
}
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index e67031fd0cb222..9366fc06d112ae 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -534,24 +534,20 @@ void VarListClauses() {
#pragma acc serial use_device(s.array[s.value : 5]), seq
for(;;){}
- // expected-error at +3{{expected ','}}
- // expected-warning at +2{{OpenACC clause 'no_create' not yet implemented, clause ignored}}
+ // expected-error at +2{{expected ','}}
// expected-warning at +1{{OpenACC clause 'seq' not yet implemented, clause ignored}}
#pragma acc serial no_create(s.array[s.value] s.array[s.value :5] ), seq
for(;;){}
- // expected-warning at +2{{OpenACC clause 'no_create' not yet implemented, clause ignored}}
// expected-warning at +1{{OpenACC clause 'seq' not yet implemented, clause ignored}}
#pragma acc serial no_create(s.array[s.value : 5], s.value), seq
for(;;){}
- // expected-error at +3{{expected ','}}
- // expected-warning at +2{{OpenACC clause 'present' not yet implemented, clause ignored}}
+ // expected-error at +2{{expected ','}}
// expected-warning at +1{{OpenACC clause 'seq' not yet implemented, clause ignored}}
#pragma acc serial present(s.array[s.value] s.array[s.value :5] ), seq
for(;;){}
- // expected-warning at +2{{OpenACC clause 'present' not yet implemented, clause ignored}}
// expected-warning at +1{{OpenACC clause 'seq' not yet implemented, clause ignored}}
#pragma acc serial present(s.array[s.value : 5], s.value), seq
for(;;){}
diff --git a/clang/test/SemaOpenACC/compute-construct-no_create-clause.c b/clang/test/SemaOpenACC/compute-construct-no_create-clause.c
new file mode 100644
index 00000000000000..07a60b73c34f84
--- /dev/null
+++ b/clang/test/SemaOpenACC/compute-construct-no_create-clause.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+typedef struct IsComplete {
+ struct S { int A; } CompositeMember;
+ int ScalarMember;
+ float ArrayMember[5];
+ void *PointerMember;
+} Complete;
+void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
+ int LocalInt;
+ short *LocalPointer;
+ float LocalArray[5];
+ Complete LocalComposite;
+ // Check Appertainment:
+#pragma acc parallel no_create(LocalInt)
+ while(1);
+#pragma acc serial no_create(LocalInt)
+ while(1);
+#pragma acc kernels no_create(LocalInt)
+ while(1);
+
+ // Valid cases:
+#pragma acc parallel no_create(LocalInt, LocalPointer, LocalArray)
+ while(1);
+#pragma acc parallel no_create(LocalArray[2:1])
+ while(1);
+
+#pragma acc parallel no_create(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
+ while(1);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create(1 + IntParam)
+ while(1);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create(+IntParam)
+ while(1);
+
+ // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel no_create(PointerParam[2:])
+ while(1);
+
+ // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel no_create(ArrayParam[2:5])
+ while(1);
+
+ // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create((float*)ArrayParam[2:5])
+ while(1);
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create((float)ArrayParam[2])
+ while(1);
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-no_create-clause.cpp b/clang/test/SemaOpenACC/compute-construct-no_create-clause.cpp
new file mode 100644
index 00000000000000..3820d5e3999d56
--- /dev/null
+++ b/clang/test/SemaOpenACC/compute-construct-no_create-clause.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+enum SomeE{};
+typedef struct IsComplete {
+ struct S { int A; } CompositeMember;
+ int ScalarMember;
+ float ArrayMember[5];
+ SomeE EnumMember;
+ char *PointerMember;
+} Complete;
+
+void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
+ int LocalInt;
+ char *LocalPointer;
+ float LocalArray[5];
+ // Check Appertainment:
+#pragma acc parallel no_create(LocalInt)
+ while(1);
+#pragma acc serial no_create(LocalInt)
+ while(1);
+#pragma acc kernels no_create(LocalInt)
+ while(1);
+
+ // Valid cases:
+#pragma acc parallel no_create(LocalInt, LocalPointer, LocalArray)
+ while(1);
+#pragma acc parallel no_create(LocalArray[2:1])
+ while(1);
+
+ Complete LocalComposite2;
+#pragma acc parallel no_create(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
+ while(1);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create(1 + IntParam)
+ while(1);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create(+IntParam)
+ while(1);
+
+ // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel no_create(PointerParam[2:])
+ while(1);
+
+ // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel no_create(ArrayParam[2:5])
+ while(1);
+
+ // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create((float*)ArrayParam[2:5])
+ while(1);
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create((float)ArrayParam[2])
+ while(1);
+}
+
+template<typename T, unsigned I, typename V>
+void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create(+t)
+ while(true);
+
+ // NTTP's are only valid if it is a reference to something.
+ // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+ // expected-note@#TEMPL_USES_INST{{in instantiation of}}
+#pragma acc parallel no_create(I)
+ while(true);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel no_create(t, I)
+ while(true);
+
+#pragma acc parallel no_create(arrayT)
+ while(true);
+
+#pragma acc parallel no_create(TemplComp)
+ while(true);
+
+#pragma acc parallel no_create(TemplComp.PointerMember[5])
+ while(true);
+ int *Pointer;
+#pragma acc parallel no_create(Pointer[:I])
+ while(true);
+#pragma acc parallel no_create(Pointer[:t])
+ while(true);
+ // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel no_create(Pointer[1:])
+ while(true);
+}
+
+template<unsigned I, auto &NTTP_REF>
+void NTTP() {
+ // NTTP's are only valid if it is a reference to something.
+ // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+ // expected-note@#NTTP_INST{{in instantiation of}}
+#pragma acc parallel no_create(I)
+ while(true);
+
+#pragma acc parallel no_create(NTTP_REF)
+ while(true);
+}
+
+void Inst() {
+ static constexpr int NTTP_REFed = 1;
+ int i;
+ int Arr[5];
+ Complete C;
+ TemplUses(i, Arr, C); // #TEMPL_USES_INST
+ NTTP<5, NTTP_REFed>(); // #NTTP_INST
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-present-clause.c b/clang/test/SemaOpenACC/compute-construct-present-clause.c
new file mode 100644
index 00000000000000..99c4b1dcd19b47
--- /dev/null
+++ b/clang/test/SemaOpenACC/compute-construct-present-clause.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+typedef struct IsComplete {
+ struct S { int A; } CompositeMember;
+ int ScalarMember;
+ float ArrayMember[5];
+ void *PointerMember;
+} Complete;
+void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
+ int LocalInt;
+ short *LocalPointer;
+ float LocalArray[5];
+ Complete LocalComposite;
+ // Check Appertainment:
+#pragma acc parallel present(LocalInt)
+ while(1);
+#pragma acc serial present(LocalInt)
+ while(1);
+#pragma acc kernels present(LocalInt)
+ while(1);
+
+ // Valid cases:
+#pragma acc parallel present(LocalInt, LocalPointer, LocalArray)
+ while(1);
+#pragma acc parallel present(LocalArray[2:1])
+ while(1);
+
+#pragma acc parallel present(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
+ while(1);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present(1 + IntParam)
+ while(1);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present(+IntParam)
+ while(1);
+
+ // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel present(PointerParam[2:])
+ while(1);
+
+ // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel present(ArrayParam[2:5])
+ while(1);
+
+ // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present((float*)ArrayParam[2:5])
+ while(1);
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present((float)ArrayParam[2])
+ while(1);
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-present-clause.cpp b/clang/test/SemaOpenACC/compute-construct-present-clause.cpp
new file mode 100644
index 00000000000000..62e481dea3e24a
--- /dev/null
+++ b/clang/test/SemaOpenACC/compute-construct-present-clause.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+enum SomeE{};
+typedef struct IsComplete {
+ struct S { int A; } CompositeMember;
+ int ScalarMember;
+ float ArrayMember[5];
+ SomeE EnumMember;
+ char *PointerMember;
+} Complete;
+
+void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
+ int LocalInt;
+ char *LocalPointer;
+ float LocalArray[5];
+ // Check Appertainment:
+#pragma acc parallel present(LocalInt)
+ while(1);
+#pragma acc serial present(LocalInt)
+ while(1);
+#pragma acc kernels present(LocalInt)
+ while(1);
+
+ // Valid cases:
+#pragma acc parallel present(LocalInt, LocalPointer, LocalArray)
+ while(1);
+#pragma acc parallel present(LocalArray[2:1])
+ while(1);
+
+ Complete LocalComposite2;
+#pragma acc parallel present(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
+ while(1);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present(1 + IntParam)
+ while(1);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present(+IntParam)
+ while(1);
+
+ // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel present(PointerParam[2:])
+ while(1);
+
+ // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel present(ArrayParam[2:5])
+ while(1);
+
+ // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present((float*)ArrayParam[2:5])
+ while(1);
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present((float)ArrayParam[2])
+ while(1);
+}
+
+template<typename T, unsigned I, typename V>
+void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present(+t)
+ while(true);
+
+ // NTTP's are only valid if it is a reference to something.
+ // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+ // expected-note@#TEMPL_USES_INST{{in instantiation of}}
+#pragma acc parallel present(I)
+ while(true);
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+#pragma acc parallel present(t, I)
+ while(true);
+
+#pragma acc parallel present(arrayT)
+ while(true);
+
+#pragma acc parallel present(TemplComp)
+ while(true);
+
+#pragma acc parallel present(TemplComp.PointerMember[5])
+ while(true);
+ int *Pointer;
+#pragma acc parallel present(Pointer[:I])
+ while(true);
+#pragma acc parallel present(Pointer[:t])
+ while(true);
+ // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel present(Pointer[1:])
+ while(true);
+}
+
+template<unsigned I, auto &NTTP_REF>
+void NTTP() {
+ // NTTP's are only valid if it is a reference to something.
+ // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}}
+ // expected-note@#NTTP_INST{{in instantiation of}}
+#pragma acc parallel present(I)
+ while(true);
+
+#pragma acc parallel present(NTTP_REF)
+ while(true);
+}
+
+void Inst() {
+ static constexpr int NTTP_REFed = 1;
+ int i;
+ int Arr[5];
+ Complete C;
+ TemplUses(i, Arr, C); // #TEMPL_USES_INST
+ NTTP<5, NTTP_REFed>(); // #NTTP_INST
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp b/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
index 8d9b678c8284fb..7bdbaad977559a 100644
--- a/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
@@ -49,6 +49,34 @@ void NormalUses(float *PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
+#pragma acc parallel present(GlobalArray, PointerParam[Global])
+ while(true);
+ // CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
+ // CHECK-NEXT: present clause
+ // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
+ // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
+ // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
+ // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
+ // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
+ // CHECK-NEXT: WhileStmt
+ // CHECK-NEXT: CXXBoolLiteralExpr
+ // CHECK-NEXT: NullStmt
+
+#pragma acc parallel no_create(GlobalArray, PointerParam[Global])
+ while(true);
+ // CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
+ // CHECK-NEXT: no_create clause
+ // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
+ // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
+ // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
+ // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
+ // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
+ // CHECK-NEXT: WhileStmt
+ // CHECK-NEXT: CXXBoolLiteralExpr
+ // CHECK-NEXT: NullStmt
+
#pragma acc parallel private(GlobalArray) private(PointerParam[Global])
while(true);
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
@@ -203,6 +231,18 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
+#pragma acc parallel no_create(t) present(NTTP, u)
+ while(true);
+ // CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
+ // CHECK-NEXT: no_create clause
+ // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+ // CHECK-NEXT: present clause
+ // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
+ // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
+ // CHECK-NEXT: WhileStmt
+ // CHECK-NEXT: CXXBoolLiteralExpr
+ // CHECK-NEXT: NullStmt
+
#pragma acc parallel private(u[0])
while(true);
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
@@ -311,6 +351,19 @@ void TemplUses(T t, U u, T*PointerParam) {
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: NullStmt
+// #pragma acc parallel no_create(t) present(NTTP, u)
+ // CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
+ // CHECK-NEXT: no_create clause
+ // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+ // CHECK-NEXT: present clause
+ // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
+ // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
+ // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
+ // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
+ // CHECK-NEXT: WhileStmt
+ // CHECK-NEXT: CXXBoolLiteralExpr
+ // CHECK-NEXT: NullStmt
+
// #pragma acc parallel private(u[0])
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
// CHECK-NEXT: private clause
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 3f67fb93208954..76249e10a0a819 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2816,10 +2816,18 @@ void OpenACCClauseEnqueue::VisitNumGangsClause(const OpenACCNumGangsClause &C) {
void OpenACCClauseEnqueue::VisitPrivateClause(const OpenACCPrivateClause &C) {
VisitVarList(C);
}
+
void OpenACCClauseEnqueue::VisitFirstPrivateClause(
const OpenACCFirstPrivateClause &C) {
VisitVarList(C);
}
+
+void OpenACCClauseEnqueue::VisitPresentClause(const OpenACCPresentClause &C) {
+ VisitVarList(C);
+}
+void OpenACCClauseEnqueue::VisitNoCreateClause(const OpenACCNoCreateClause &C) {
+ VisitVarList(C);
+}
} // namespace
void EnqueueVisitor::EnqueueChildren(const OpenACCClause *C) {
More information about the cfe-commits
mailing list