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@+2{{expected ','}}
-  // expected-warning@+1{{OpenACC clause 'delete' not yet implemented, clause 
ignored}}
+  // expected-error@+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@+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@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+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@+1{{previous clause is here}}
 #pragma acc parallel loop device_type(*) attach(Var)
   for(int i = 0; i < 5; ++i);
-  // expected-error@+2{{OpenACC clause 'delete' may not follow a 'device_type' 
clause in a 'serial loop' construct}}
-  // expected-note@+1{{previous clause is here}}
+  // expected-error@+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@+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@+1{{previous clause is here}}
 #pragma acc kernels device_type(*) attach(Var)
   while(1);
-  // expected-error@+2{{OpenACC clause 'delete' may not follow a 'device_type' 
clause in a 'kernels' construct}}
-  // expected-note@+1{{previous clause is here}}
+  // expected-error@+1{{OpenACC 'delete' clause is not valid on 'kernels' 
directive}}
 #pragma acc kernels device_type(*) delete(Var)
   while(1);
   // expected-error@+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@+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@+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@+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@+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@+2{{OpenACC sub-array specified range [2:5] would be out 
of the range of the subscripted array size of 5}}
+  // expected-error@+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@+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@+1{{OpenACC 'delete' clause is not valid on 'data' 
directive}}
+#pragma acc data delete(LocalInt)
+  ;
+  // expected-error@+1{{OpenACC 'delete' clause is not valid on 'enter data' 
directive}}
+#pragma acc enter data delete(LocalInt)
+  // expected-error@+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@+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@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+1{{OpenACC 'detach' clause is not valid on 'loop' 
directive}}
@@ -208,7 +208,7 @@ void uses() {
   // expected-error@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+1{{OpenACC 'detach' clause is not valid on 'loop' 
directive}}
@@ -343,7 +343,7 @@ void uses() {
   // expected-error@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+1{{OpenACC 'detach' clause is not valid on 'loop' 
directive}}
@@ -477,7 +477,7 @@ void uses() {
   // expected-error@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+1{{OpenACC 'detach' clause is not valid on 'loop' 
directive}}
@@ -620,7 +620,7 @@ void uses() {
   // expected-error@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+1{{OpenACC 'detach' clause is not valid on 'loop' 
directive}}
@@ -760,7 +760,7 @@ void uses() {
   // expected-error@+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@+1{{OpenACC clause 'delete' not yet implemented}}
+  // expected-error@+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@+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@+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@+2{{OpenACC clause 'delete' may not follow a 'device_type' 
clause in a 'loop' construct}}
-  // expected-note@+1{{previous clause is here}}
+  // expected-error@+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@+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) {


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to