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