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