[clang] 1ab81f8 - [OpenACC] Implement 'delete' AST/Sema for 'exit data' construct
via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 16 06:44:59 PST 2024
Author: erichkeane
Date: 2024-12-16T06:44:53-08:00
New Revision: 1ab81f8e7f77110c4a752dd7d2cc39fb5148760c
URL: https://github.com/llvm/llvm-project/commit/1ab81f8e7f77110c4a752dd7d2cc39fb5148760c
DIFF: https://github.com/llvm/llvm-project/commit/1ab81f8e7f77110c4a752dd7d2cc39fb5148760c.diff
LOG: [OpenACC] Implement 'delete' AST/Sema for 'exit data' construct
'delete' is another clause that has very little compile-time
implication, but needs a full AST that takes a var list. This patch
ipmlements it fully, plus adds sufficient test coverage.
Added:
clang/test/SemaOpenACC/data-construct-delete-ast.cpp
clang/test/SemaOpenACC/data-construct-delete-clause.c
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-data-construct.cpp
clang/test/ParserOpenACC/parse-clauses.c
clang/test/ParserOpenACC/parse-clauses.cpp
clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
clang/test/SemaOpenACC/combined-construct-device_type-clause.c
clang/test/SemaOpenACC/compute-construct-device_type-clause.c
clang/test/SemaOpenACC/data-construct.cpp
clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
clang/test/SemaOpenACC/loop-construct-device_type-clause.c
clang/tools/libclang/CIndex.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h
index 7778f8199b3af6..93053c0e60758e 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -766,6 +766,29 @@ class OpenACCDetachClause final
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
};
+class OpenACCDeleteClause final
+ : public OpenACCClauseWithVarList,
+ public llvm::TrailingObjects<OpenACCDeleteClause, Expr *> {
+
+ OpenACCDeleteClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc)
+ : OpenACCClauseWithVarList(OpenACCClauseKind::Delete, BeginLoc, LParenLoc,
+ EndLoc) {
+ std::uninitialized_copy(VarList.begin(), VarList.end(),
+ getTrailingObjects<Expr *>());
+ setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
+ }
+
+public:
+ static bool classof(const OpenACCClause *C) {
+ return C->getClauseKind() == OpenACCClauseKind::Delete;
+ }
+ static OpenACCDeleteClause *
+ Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+};
+
+
class OpenACCNoCreateClause final
: public OpenACCClauseWithVarList,
public llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> {
diff --git a/clang/include/clang/Basic/OpenACCClauses.def b/clang/include/clang/Basic/OpenACCClauses.def
index 87983c3849480f..600510e6980dae 100644
--- a/clang/include/clang/Basic/OpenACCClauses.def
+++ b/clang/include/clang/Basic/OpenACCClauses.def
@@ -38,6 +38,7 @@ VISIT_CLAUSE(Create)
CLAUSE_ALIAS(PCreate, Create, true)
CLAUSE_ALIAS(PresentOrCreate, Create, true)
VISIT_CLAUSE(Default)
+VISIT_CLAUSE(Delete)
VISIT_CLAUSE(Detach)
VISIT_CLAUSE(DevicePtr)
VISIT_CLAUSE(DeviceType)
diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
index ea3f34e3f4a959..58137d3a7e3f73 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -399,6 +399,7 @@ class SemaOpenACC : public SemaBase {
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
ClauseKind == OpenACCClauseKind::Attach ||
+ ClauseKind == OpenACCClauseKind::Delete ||
ClauseKind == OpenACCClauseKind::Detach ||
ClauseKind == OpenACCClauseKind::DevicePtr ||
ClauseKind == OpenACCClauseKind::Reduction ||
@@ -536,6 +537,7 @@ class SemaOpenACC : public SemaBase {
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
ClauseKind == OpenACCClauseKind::Attach ||
+ ClauseKind == OpenACCClauseKind::Delete ||
ClauseKind == OpenACCClauseKind::Detach ||
ClauseKind == OpenACCClauseKind::DevicePtr ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
@@ -573,6 +575,7 @@ class SemaOpenACC : public SemaBase {
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
ClauseKind == OpenACCClauseKind::Attach ||
+ ClauseKind == OpenACCClauseKind::Delete ||
ClauseKind == OpenACCClauseKind::Detach ||
ClauseKind == OpenACCClauseKind::DevicePtr ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp
index d2d8f34e9014de..f836d30561e33b 100644
--- a/clang/lib/AST/OpenACCClause.cpp
+++ b/clang/lib/AST/OpenACCClause.cpp
@@ -32,7 +32,7 @@ bool OpenACCClauseWithVarList::classof(const OpenACCClause *C) {
return OpenACCPrivateClause::classof(C) ||
OpenACCFirstPrivateClause::classof(C) ||
OpenACCDevicePtrClause::classof(C) ||
- OpenACCDevicePtrClause::classof(C) ||
+ OpenACCDeleteClause::classof(C) ||
OpenACCDetachClause::classof(C) || OpenACCAttachClause::classof(C) ||
OpenACCNoCreateClause::classof(C) ||
OpenACCPresentClause::classof(C) || OpenACCCopyClause::classof(C) ||
@@ -288,6 +288,16 @@ OpenACCDetachClause *OpenACCDetachClause::Create(const ASTContext &C,
return new (Mem) OpenACCDetachClause(BeginLoc, LParenLoc, VarList, EndLoc);
}
+OpenACCDeleteClause *OpenACCDeleteClause::Create(const ASTContext &C,
+ SourceLocation BeginLoc,
+ SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList,
+ SourceLocation EndLoc) {
+ void *Mem =
+ C.Allocate(OpenACCDeleteClause::totalSizeToAlloc<Expr *>(VarList.size()));
+ return new (Mem) OpenACCDeleteClause(BeginLoc, LParenLoc, VarList, EndLoc);
+}
+
OpenACCDevicePtrClause *OpenACCDevicePtrClause::Create(const ASTContext &C,
SourceLocation BeginLoc,
SourceLocation LParenLoc,
@@ -564,6 +574,13 @@ void OpenACCClausePrinter::VisitDetachClause(const OpenACCDetachClause &C) {
OS << ")";
}
+void OpenACCClausePrinter::VisitDeleteClause(const OpenACCDeleteClause &C) {
+ OS << "delete(";
+ llvm::interleaveComma(C.getVarList(), OS,
+ [&](const Expr *E) { printExpr(E); });
+ OS << ")";
+}
+
void OpenACCClausePrinter::VisitDevicePtrClause(
const OpenACCDevicePtrClause &C) {
OS << "deviceptr(";
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 4e9865f722f78e..6160a69832e8aa 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2611,6 +2611,12 @@ void OpenACCClauseProfiler::VisitDetachClause(
Profiler.VisitStmt(E);
}
+void OpenACCClauseProfiler::VisitDeleteClause(
+ const OpenACCDeleteClause &Clause) {
+ for (auto *E : Clause.getVarList())
+ Profiler.VisitStmt(E);
+}
+
void OpenACCClauseProfiler::VisitDevicePtrClause(
const OpenACCDevicePtrClause &Clause) {
for (auto *E : Clause.getVarList())
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index b02b682fb0c58f..6040f34a4b9a5f 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -412,6 +412,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Independent:
case OpenACCClauseKind::Detach:
+ case OpenACCClauseKind::Delete:
case OpenACCClauseKind::DevicePtr:
case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::FirstPrivate:
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 5da7069edaa740..5130159f5d8ac8 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -998,7 +998,6 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
// make sure we get the right
diff erentiator.
assert(DirKind == OpenACCDirectiveKind::Update);
[[fallthrough]];
- case OpenACCClauseKind::Delete:
case OpenACCClauseKind::Device:
case OpenACCClauseKind::DeviceResident:
case OpenACCClauseKind::Host:
@@ -1007,6 +1006,7 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
ParseOpenACCVarList(ClauseKind);
break;
case OpenACCClauseKind::Attach:
+ case OpenACCClauseKind::Delete:
case OpenACCClauseKind::Detach:
case OpenACCClauseKind::DevicePtr:
ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind),
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 7156e37991284f..7af209aa155968 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -425,6 +425,15 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
return false;
}
}
+ case OpenACCClauseKind::Delete: {
+ switch (DirectiveKind) {
+ case OpenACCDirectiveKind::ExitData:
+ return true;
+ default:
+ return false;
+ }
+ }
+
case OpenACCClauseKind::Detach: {
switch (DirectiveKind) {
case OpenACCDirectiveKind::ExitData:
@@ -1066,6 +1075,17 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(
Clause.getEndLoc());
}
+OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause(
+ SemaOpenACC::OpenACCParsedClause &Clause) {
+ // 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 OpenACCDeleteClause::Create(Ctx, Clause.getBeginLoc(),
+ Clause.getLParenLoc(), Clause.getVarList(),
+ Clause.getEndLoc());
+}
+
+
OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
// Restrictions only properly implemented on 'compute'/'combined'/'data'
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 0f92186d08933c..c33648ca0e34b8 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -11777,6 +11777,17 @@ void OpenACCClauseTransform<Derived>::VisitDetachClause(
ParsedClause.getEndLoc());
}
+template <typename Derived>
+void OpenACCClauseTransform<Derived>::VisitDeleteClause(
+ const OpenACCDeleteClause &C) {
+ ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
+ /*IsReadOnly=*/false, /*IsZero=*/false);
+ NewClause = OpenACCDeleteClause::Create(
+ Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
+ ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
+ ParsedClause.getEndLoc());
+}
+
template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
const OpenACCDevicePtrClause &C) {
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 1a1b8a0e51f0cd..741bae684cffe3 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -12435,6 +12435,12 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
return OpenACCDetachClause::Create(getContext(), BeginLoc, LParenLoc,
VarList, EndLoc);
}
+ case OpenACCClauseKind::Delete: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCDeleteClause::Create(getContext(), BeginLoc, LParenLoc,
+ VarList, EndLoc);
+ }
case OpenACCClauseKind::DevicePtr: {
SourceLocation LParenLoc = readSourceLocation();
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
@@ -12578,7 +12584,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
case OpenACCClauseKind::NoHost:
case OpenACCClauseKind::UseDevice:
- case OpenACCClauseKind::Delete:
case OpenACCClauseKind::Device:
case OpenACCClauseKind::DeviceResident:
case OpenACCClauseKind::Host:
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index ffbef3a2803940..9517bad4070dfb 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -8362,6 +8362,12 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
writeOpenACCVarList(DC);
return;
}
+ case OpenACCClauseKind::Delete: {
+ const auto *DC = cast<OpenACCDeleteClause>(C);
+ writeSourceLocation(DC->getLParenLoc());
+ writeOpenACCVarList(DC);
+ return;
+ }
case OpenACCClauseKind::DevicePtr: {
const auto *DPC = cast<OpenACCDevicePtrClause>(C);
writeSourceLocation(DPC->getLParenLoc());
@@ -8506,7 +8512,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
case OpenACCClauseKind::NoHost:
case OpenACCClauseKind::UseDevice:
- case OpenACCClauseKind::Delete:
case OpenACCClauseKind::Device:
case OpenACCClauseKind::DeviceResident:
case OpenACCClauseKind::Host:
diff --git a/clang/test/AST/ast-print-openacc-data-construct.cpp b/clang/test/AST/ast-print-openacc-data-construct.cpp
index 003dc03f342c15..f03f96239ab4c6 100644
--- a/clang/test/AST/ast-print-openacc-data-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-data-construct.cpp
@@ -120,4 +120,10 @@ void foo() {
// CHECK: #pragma acc exit data copyout(i) detach(iPtr, arrayPtr[0])
#pragma acc exit data copyout(i) detach(iPtr, arrayPtr[0])
+// CHECK: #pragma acc exit data copyout(i) delete(i, array[1], array, array[1:2])
+#pragma acc exit data copyout(i) delete(i, array[1], array, array[1:2])
+ ;
+
+// CHECK: #pragma acc exit data copyout(i) delete(i, array[1], array, array[1:2])
+#pragma acc exit data copyout(i) delete(i, array[1], array, array[1:2])
}
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index 0498fe16e512cd..e583fb3897998d 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -510,12 +510,10 @@ void VarListClauses() {
#pragma acc serial firstprivate(s.array[s.value : 5], s.value), self
for(int i = 0; i < 5;++i) {}
- // expected-error at +2{{expected ','}}
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented, clause ignored}}
+ // expected-error at +1{{expected ','}}
#pragma acc exit data delete(s.array[s.value] s.array[s.value :5] ) async
for(int i = 0; i < 5;++i) {}
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented, clause ignored}}
#pragma acc exit data delete(s.array[s.value : 5], s.value),async
for(int i = 0; i < 5;++i) {}
diff --git a/clang/test/ParserOpenACC/parse-clauses.cpp b/clang/test/ParserOpenACC/parse-clauses.cpp
index 1781a279407543..770bc3b976c967 100644
--- a/clang/test/ParserOpenACC/parse-clauses.cpp
+++ b/clang/test/ParserOpenACC/parse-clauses.cpp
@@ -35,8 +35,9 @@ void templ() {
#pragma acc parallel async
for(;;){}
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented, clause ignored}}
-#pragma acc exit data delete(I)
+
+ T t;
+#pragma acc exit data delete(t)
;
}
diff --git a/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c b/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
index b1d682c0ea5b39..a9f6f1e6b9e3a3 100644
--- a/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
+++ b/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
@@ -69,7 +69,7 @@ void uses() {
for(unsigned i = 0; i < 5; ++i);
#pragma acc parallel loop auto attach(VarPtr)
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}}
#pragma acc parallel loop auto delete(Var)
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
@@ -186,7 +186,7 @@ void uses() {
for(unsigned i = 0; i < 5; ++i);
#pragma acc parallel loop attach(VarPtr) auto
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}}
#pragma acc parallel loop delete(Var) auto
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
@@ -304,7 +304,7 @@ void uses() {
for(unsigned i = 0; i < 5; ++i);
#pragma acc parallel loop independent attach(VarPtr)
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}}
#pragma acc parallel loop independent delete(Var)
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
@@ -421,7 +421,7 @@ void uses() {
for(unsigned i = 0; i < 5; ++i);
#pragma acc parallel loop attach(VarPtr) independent
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}}
#pragma acc parallel loop delete(Var) independent
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
@@ -547,7 +547,7 @@ void uses() {
for(unsigned i = 0; i < 5; ++i);
#pragma acc parallel loop seq attach(VarPtr)
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}}
#pragma acc parallel loop seq delete(Var)
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
@@ -670,7 +670,7 @@ void uses() {
for(unsigned i = 0; i < 5; ++i);
#pragma acc parallel loop attach(VarPtr) seq
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}}
#pragma acc parallel loop delete(Var) seq
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}}
diff --git a/clang/test/SemaOpenACC/combined-construct-device_type-clause.c b/clang/test/SemaOpenACC/combined-construct-device_type-clause.c
index cc8d8adbdc9f1c..4526a11eeb9079 100644
--- a/clang/test/SemaOpenACC/combined-construct-device_type-clause.c
+++ b/clang/test/SemaOpenACC/combined-construct-device_type-clause.c
@@ -95,8 +95,7 @@ void uses() {
// expected-note at +1{{previous clause is here}}
#pragma acc parallel loop device_type(*) attach(Var)
for(int i = 0; i < 5; ++i);
- // expected-error at +2{{OpenACC clause 'delete' may not follow a 'device_type' clause in a 'serial loop' construct}}
- // expected-note at +1{{previous clause is here}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'serial loop' directive}}
#pragma acc serial loop device_type(*) delete(Var)
for(int i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'kernels loop' directive}}
diff --git a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c
index 6c7233e06d7758..6f46e615f43c9d 100644
--- a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c
@@ -99,8 +99,7 @@ void uses() {
// expected-note at +1{{previous clause is here}}
#pragma acc kernels device_type(*) attach(Var)
while(1);
- // expected-error at +2{{OpenACC clause 'delete' may not follow a 'device_type' clause in a 'kernels' construct}}
- // expected-note at +1{{previous clause is here}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'kernels' directive}}
#pragma acc kernels device_type(*) delete(Var)
while(1);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'kernels' directive}}
diff --git a/clang/test/SemaOpenACC/data-construct-delete-ast.cpp b/clang/test/SemaOpenACC/data-construct-delete-ast.cpp
new file mode 100644
index 00000000000000..b61fdc900928dd
--- /dev/null
+++ b/clang/test/SemaOpenACC/data-construct-delete-ast.cpp
@@ -0,0 +1,58 @@
+
+// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s
+
+// Test this with PCH.
+// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s
+// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s
+
+#ifndef PCH_HELPER
+#define PCH_HELPER
+
+int Global;
+short GlobalArray[5];
+void NormalUses(float *PointerParam) {
+ // CHECK: FunctionDecl{{.*}}NormalUses
+ // CHECK: ParmVarDecl
+ // CHECK-NEXT: CompoundStmt
+
+#pragma acc exit data delete(GlobalArray, PointerParam[Global])
+ // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data
+ // CHECK-NEXT: delete 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'
+}
+
+template<typename T>
+void TemplUses(T t) {
+ // CHECK-NEXT: FunctionTemplateDecl
+ // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 0 T
+ // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T)'
+ // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
+ // CHECK-NEXT: CompoundStmt
+
+#pragma acc exit data delete(t)
+ // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data
+ // CHECK-NEXT: delete clause
+ // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+
+ // Check the instantiated versions of the above.
+ // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int)' implicit_instantiation
+ // CHECK-NEXT: TemplateArgument type 'int'
+ // CHECK-NEXT: BuiltinType{{.*}} 'int'
+ // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
+ // CHECK-NEXT: CompoundStmt
+
+ // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data
+ // CHECK-NEXT: delete clause
+ // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+}
+
+void Inst() {
+ int i;
+ TemplUses(i);
+}
+#endif
diff --git a/clang/test/SemaOpenACC/data-construct-delete-clause.c b/clang/test/SemaOpenACC/data-construct-delete-clause.c
new file mode 100644
index 00000000000000..d936882ae94214
--- /dev/null
+++ b/clang/test/SemaOpenACC/data-construct-delete-clause.c
@@ -0,0 +1,48 @@
+// 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 exit data delete(LocalInt)
+
+ // Valid cases:
+#pragma acc exit data delete(LocalInt, LocalPointer, LocalArray)
+#pragma acc exit data delete(LocalArray[2:1])
+#pragma acc exit data delete(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc exit data delete(1 + IntParam)
+
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc exit data delete(+IntParam)
+
+ // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc exit data delete(PointerParam[2:])
+
+ // 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 exit data delete(ArrayParam[2:5])
+
+ // 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, member of a composite variable, or composite variable member}}
+#pragma acc exit data delete((float*)ArrayParam[2:5])
+ // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc exit data delete((float)ArrayParam[2])
+
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'data' directive}}
+#pragma acc data delete(LocalInt)
+ ;
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'enter data' directive}}
+#pragma acc enter data delete(LocalInt)
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'host_data' directive}}
+#pragma acc host_data delete(LocalInt)
+ ;
+}
diff --git a/clang/test/SemaOpenACC/data-construct.cpp b/clang/test/SemaOpenACC/data-construct.cpp
index 1fcf147b0f1b34..507cc5ac5cfaf5 100644
--- a/clang/test/SemaOpenACC/data-construct.cpp
+++ b/clang/test/SemaOpenACC/data-construct.cpp
@@ -73,7 +73,6 @@ void AtLeastOneOf() {
// Exit Data
#pragma acc exit data copyout(Var)
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
#pragma acc exit data delete(Var)
#pragma acc exit data detach(VarPtr)
diff --git a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
index e1e35d6a7b36e0..bbd04e7afa6f25 100644
--- a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
+++ b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
@@ -74,7 +74,7 @@ void uses() {
// expected-error at +1{{OpenACC 'attach' clause is not valid on 'loop' directive}}
#pragma acc loop auto attach(Var)
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'loop' directive}}
#pragma acc loop auto delete(Var)
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'loop' directive}}
@@ -208,7 +208,7 @@ void uses() {
// expected-error at +1{{OpenACC 'attach' clause is not valid on 'loop' directive}}
#pragma acc loop attach(Var) auto
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'loop' directive}}
#pragma acc loop delete(Var) auto
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'loop' directive}}
@@ -343,7 +343,7 @@ void uses() {
// expected-error at +1{{OpenACC 'attach' clause is not valid on 'loop' directive}}
#pragma acc loop independent attach(Var)
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'loop' directive}}
#pragma acc loop independent delete(Var)
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'loop' directive}}
@@ -477,7 +477,7 @@ void uses() {
// expected-error at +1{{OpenACC 'attach' clause is not valid on 'loop' directive}}
#pragma acc loop attach(Var) independent
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'loop' directive}}
#pragma acc loop delete(Var) independent
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'loop' directive}}
@@ -620,7 +620,7 @@ void uses() {
// expected-error at +1{{OpenACC 'attach' clause is not valid on 'loop' directive}}
#pragma acc loop seq attach(Var)
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'loop' directive}}
#pragma acc loop seq delete(Var)
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'loop' directive}}
@@ -760,7 +760,7 @@ void uses() {
// expected-error at +1{{OpenACC 'attach' clause is not valid on 'loop' directive}}
#pragma acc loop attach(Var) seq
for(unsigned i = 0; i < 5; ++i);
- // expected-warning at +1{{OpenACC clause 'delete' not yet implemented}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'loop' directive}}
#pragma acc loop delete(Var) seq
for(unsigned i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'loop' directive}}
diff --git a/clang/test/SemaOpenACC/loop-construct-device_type-clause.c b/clang/test/SemaOpenACC/loop-construct-device_type-clause.c
index 94eb2672e8111e..8fc6690273c7de 100644
--- a/clang/test/SemaOpenACC/loop-construct-device_type-clause.c
+++ b/clang/test/SemaOpenACC/loop-construct-device_type-clause.c
@@ -87,8 +87,7 @@ void uses() {
// expected-error at +1{{OpenACC 'attach' clause is not valid on 'loop' directive}}
#pragma acc loop device_type(*) attach(Var)
for(int i = 0; i < 5; ++i);
- // expected-error at +2{{OpenACC clause 'delete' may not follow a 'device_type' clause in a 'loop' construct}}
- // expected-note at +1{{previous clause is here}}
+ // expected-error at +1{{OpenACC 'delete' clause is not valid on 'loop' directive}}
#pragma acc loop device_type(*) delete(Var)
for(int i = 0; i < 5; ++i);
// expected-error at +1{{OpenACC 'detach' clause is not valid on 'loop' directive}}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 8d6994128f2f07..d1a28624618990 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2890,6 +2890,9 @@ void OpenACCClauseEnqueue::VisitAttachClause(const OpenACCAttachClause &C) {
void OpenACCClauseEnqueue::VisitDetachClause(const OpenACCDetachClause &C) {
VisitVarList(C);
}
+void OpenACCClauseEnqueue::VisitDeleteClause(const OpenACCDeleteClause &C) {
+ VisitVarList(C);
+}
void OpenACCClauseEnqueue::VisitDevicePtrClause(
const OpenACCDevicePtrClause &C) {
More information about the cfe-commits
mailing list