[clang] 1f2aeef - [OpenACC] Enable copy/create clauses for combined constructs

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 2 11:15:41 PST 2024


Author: erichkeane
Date: 2024-12-02T11:15:35-08:00
New Revision: 1f2aeef97bf229821b1b254d7ce4e3d1c7f8683f

URL: https://github.com/llvm/llvm-project/commit/1f2aeef97bf229821b1b254d7ce4e3d1c7f8683f
DIFF: https://github.com/llvm/llvm-project/commit/1f2aeef97bf229821b1b254d7ce4e3d1c7f8683f.diff

LOG: [OpenACC] Enable copy/create clauses for combined constructs

This is the last set of 'no op' changes, and are all incredibly similar,
so they are being done together.  They work the exact same for combined
constructs as they do for compute constructs, so this adds tests and
enables them.

Added: 
    clang/test/SemaOpenACC/combined-construct-copy-ast.cpp
    clang/test/SemaOpenACC/combined-construct-copy-clause.c
    clang/test/SemaOpenACC/combined-construct-copy-clause.cpp
    clang/test/SemaOpenACC/combined-construct-copyin-ast.cpp
    clang/test/SemaOpenACC/combined-construct-copyin-clause.c
    clang/test/SemaOpenACC/combined-construct-copyin-clause.cpp
    clang/test/SemaOpenACC/combined-construct-copyout-ast.cpp
    clang/test/SemaOpenACC/combined-construct-copyout-clause.c
    clang/test/SemaOpenACC/combined-construct-copyout-clause.cpp
    clang/test/SemaOpenACC/combined-construct-create-ast.cpp
    clang/test/SemaOpenACC/combined-construct-create-clause.c
    clang/test/SemaOpenACC/combined-construct-create-clause.cpp

Modified: 
    clang/lib/Sema/SemaOpenACC.cpp
    clang/test/AST/ast-print-openacc-combined-construct.cpp
    clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
    clang/test/SemaOpenACC/combined-construct-default-clause.c
    clang/test/SemaOpenACC/combined-construct-default-clause.cpp
    clang/test/SemaOpenACC/compute-construct-default-clause.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 80226d0524783f..8775327a25f66a 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -877,10 +877,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
 
 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
     SemaOpenACC::OpenACCParsedClause &Clause) {
-  // 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()))
+  // Restrictions only properly implemented on 'compute'/'combined' constructs,
+  // and 'compute'/'combined' constructs are the only construct that can do
+  // anything with this yet, so skip/treat as unimplemented in this case.
+  if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
+      !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
     return isNotImplemented();
   // ActOnVar ensured that everything is a valid variable reference, so there
   // really isn't anything to do here. GCC does some duplicate-finding, though
@@ -893,10 +894,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
 
 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
     SemaOpenACC::OpenACCParsedClause &Clause) {
-  // 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()))
+  // Restrictions only properly implemented on 'compute'/'combined' constructs,
+  // and 'compute'/'combined' constructs are the only construct that can do
+  // anything with this yet, so skip/treat as unimplemented in this case.
+  if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
+      !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
     return isNotImplemented();
   // ActOnVar ensured that everything is a valid variable reference, so there
   // really isn't anything to do here. GCC does some duplicate-finding, though
@@ -909,10 +911,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
 
 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
     SemaOpenACC::OpenACCParsedClause &Clause) {
-  // 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()))
+  // Restrictions only properly implemented on 'compute'/'combined' constructs,
+  // and 'compute'/'combined' constructs are the only construct that can do
+  // anything with this yet, so skip/treat as unimplemented in this case.
+  if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
+      !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
     return isNotImplemented();
   // ActOnVar ensured that everything is a valid variable reference, so there
   // really isn't anything to do here. GCC does some duplicate-finding, though
@@ -925,10 +928,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
 
 OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
     SemaOpenACC::OpenACCParsedClause &Clause) {
-  // 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()))
+  // Restrictions only properly implemented on 'compute'/'combined' constructs,
+  // and 'compute'/'combined' constructs are the only construct that can do
+  // anything with this yet, so skip/treat as unimplemented in this case.
+  if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
+      !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
     return isNotImplemented();
   // ActOnVar ensured that everything is a valid variable reference, so there
   // really isn't anything to do here. GCC does some duplicate-finding, though

diff  --git a/clang/test/AST/ast-print-openacc-combined-construct.cpp b/clang/test/AST/ast-print-openacc-combined-construct.cpp
index 16f0b3b49a7b74..114c0bb1c739af 100644
--- a/clang/test/AST/ast-print-openacc-combined-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-combined-construct.cpp
@@ -170,4 +170,19 @@ void foo() {
 #pragma acc parallel loop no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2])
   for(int i = 0;i<5;++i);
 
+// CHECK: #pragma acc parallel loop copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
+#pragma acc parallel loop copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
+  for(int i = 0;i<5;++i);
+
+// CHECK: #pragma acc parallel loop copyin(i, array[1], array, array[1:2]) pcopyin(readonly: i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2])
+#pragma acc parallel loop copyin(i, array[1], array, array[1:2]) pcopyin(readonly:i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2])
+  for(int i = 0;i<5;++i);
+
+// CHECK: #pragma acc parallel loop copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2])
+#pragma acc parallel loop copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2])
+  for(int i = 0;i<5;++i);
+
+// CHECK: #pragma acc parallel loop create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2])
+#pragma acc parallel loop create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2])
+  for(int i = 0;i<5;++i);
 }

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 cbd613b00c6ae9..c614bbbd1d1769 100644
--- a/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
+++ b/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
@@ -61,18 +61,12 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop auto self
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copy' not yet implemented}}
 #pragma acc parallel loop auto copy(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'pcopy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop auto pcopy(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop auto present_or_copy(Var)
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'use_device' not yet implemented}}
@@ -108,46 +102,28 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop auto private(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyout' not yet implemented}}
 #pragma acc parallel loop auto copyout(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop auto pcopyout(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop auto present_or_copyout(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyin' not yet implemented}}
 #pragma acc parallel loop auto copyin(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop auto pcopyin(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop auto present_or_copyin(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'create' not yet implemented}}
 #pragma acc parallel loop auto create(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcreate' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'pcreate' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop auto pcreate(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_create' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop auto present_or_create(Var)
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'reduction' not yet implemented}}
@@ -214,18 +190,12 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop self auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copy' not yet implemented}}
 #pragma acc parallel loop copy(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'pcopy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop pcopy(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop present_or_copy(Var) auto
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'use_device' not yet implemented}}
@@ -261,46 +231,28 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop private(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyout' not yet implemented}}
 #pragma acc parallel loop copyout(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop pcopyout(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop present_or_copyout(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyin' not yet implemented}}
 #pragma acc parallel loop copyin(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop pcopyin(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop present_or_copyin(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'create' not yet implemented}}
 #pragma acc parallel loop create(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcreate' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'pcreate' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop pcreate(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_create' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop present_or_create(Var) auto
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'reduction' not yet implemented}}
@@ -368,18 +320,12 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop independent self
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copy' not yet implemented}}
 #pragma acc parallel loop independent copy(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'pcopy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop independent pcopy(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop independent present_or_copy(Var)
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'use_device' not yet implemented}}
@@ -415,46 +361,28 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop independent private(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyout' not yet implemented}}
 #pragma acc parallel loop independent copyout(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop independent pcopyout(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop independent present_or_copyout(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyin' not yet implemented}}
 #pragma acc parallel loop independent copyin(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop independent pcopyin(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop independent present_or_copyin(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'create' not yet implemented}}
 #pragma acc parallel loop independent create(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcreate' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'pcreate' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop independent pcreate(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_create' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop independent present_or_create(Var)
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'reduction' not yet implemented}}
@@ -521,18 +449,12 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop self independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copy' not yet implemented}}
 #pragma acc parallel loop copy(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'pcopy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop pcopy(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop present_or_copy(Var) independent
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'use_device' not yet implemented}}
@@ -568,46 +490,28 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop private(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyout' not yet implemented}}
 #pragma acc parallel loop copyout(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TDOOexpected-error at +1{{OpenACC 'pcopyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop pcopyout(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop present_or_copyout(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TDOOexpected-error at +1{{OpenACC 'copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyin' not yet implemented}}
 #pragma acc parallel loop copyin(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop pcopyin(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop present_or_copyin(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'create' not yet implemented}}
 #pragma acc parallel loop create(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcreate' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'pcreate' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop pcreate(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_create' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop present_or_create(Var) independent
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'reduction' not yet implemented}}
@@ -681,18 +585,12 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop seq self
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copy' not yet implemented}}
 #pragma acc parallel loop seq copy(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'pcopy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop seq pcopy(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop seq present_or_copy(Var)
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'use_device' not yet implemented}}
@@ -728,46 +626,28 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop seq private(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyout' not yet implemented}}
 #pragma acc parallel loop seq copyout(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop seq pcopyout(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop seq present_or_copyout(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyin' not yet implemented}}
 #pragma acc parallel loop seq copyin(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop seq pcopyin(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop seq present_or_copyin(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'create' not yet implemented}}
 #pragma acc parallel loop seq create(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcreate' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'pcreate' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop seq pcreate(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_create' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop seq present_or_create(Var)
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'reduction' not yet implemented}}
@@ -840,18 +720,12 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop self seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copy' not yet implemented}}
 #pragma acc parallel loop copy(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'pcopy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop pcopy(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copy' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copy' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
 #pragma acc parallel loop present_or_copy(Var) seq
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'use_device' not yet implemented}}
@@ -887,46 +761,28 @@ void uses() {
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop private(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyout' not yet implemented}}
 #pragma acc parallel loop copyout(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop pcopyout(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyout' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyout' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
 #pragma acc parallel loop present_or_copyout(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'copyin' not yet implemented}}
 #pragma acc parallel loop copyin(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcopyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'pcopyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop pcopyin(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_copyin' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_copyin' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
 #pragma acc parallel loop present_or_copyin(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'create' not yet implemented}}
 #pragma acc parallel loop create(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'pcreate' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'pcreate' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop pcreate(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present_or_create' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +2{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
-  // expected-warning at +1{{OpenACC clause 'present_or_create' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
 #pragma acc parallel loop present_or_create(Var) seq
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'reduction' not yet implemented}}

diff  --git a/clang/test/SemaOpenACC/combined-construct-copy-ast.cpp b/clang/test/SemaOpenACC/combined-construct-copy-ast.cpp
new file mode 100644
index 00000000000000..a696badb0847cf
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-copy-ast.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s
+
+// Test this with PCH.
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -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 parallel loop copy(GlobalArray) pcopy(PointerParam[Global]) present_or_copy(Global)
+  for (unsigned i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: copy clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
+  // CHECK-NEXT: pcopy clause
+  // 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: present_or_copy clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
+  // CHECK-NEXT: ForStmt
+  // CHECK:NullStmt
+}
+
+template<auto &NTTP, typename T, typename U>
+void TemplUses(T t, U u) {
+  // CHECK-NEXT: FunctionTemplateDecl
+  // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U
+  // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)'
+  // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
+  // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
+  // CHECK-NEXT: CompoundStmt
+
+#pragma acc parallel loop copy(t) pcopy(NTTP, u) present_or_copy(u[0:t])
+  for (unsigned i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: copy clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+  // CHECK-NEXT: pcopy clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
+  // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
+  // CHECK-NEXT: present_or_copy clause
+  // CHECK-NEXT: ArraySectionExpr
+  // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
+  // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
+  // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+  // CHECK-NEXT: ForStmt
+  // CHECK:NullStmt
+
+  // Check the instantiated versions of the above.
+  // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation
+  // CHECK-NEXT: TemplateArgument decl
+  // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
+  // CHECK-NEXT: TemplateArgument type 'int'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: TemplateArgument type 'int *'
+  // CHECK-NEXT: PointerType{{.*}} 'int *'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
+  // CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *'
+  // CHECK-NEXT: CompoundStmt
+
+// #pragma acc parallel copy(t) pcopy(NTTP, u) present_or_copy(u[0:t])
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: copy clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+  // CHECK-NEXT: pcopy 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: present_or_copy clause
+  // CHECK-NEXT: ArraySectionExpr
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
+  // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+  // CHECK-NEXT: ForStmt
+  // CHECK:NullStmt
+}
+
+void Inst() {
+  static constexpr unsigned CEVar = 1;
+  int i;
+  TemplUses<CEVar>(i, &i);
+}
+#endif

diff  --git a/clang/test/SemaOpenACC/combined-construct-copy-clause.c b/clang/test/SemaOpenACC/combined-construct-copy-clause.c
new file mode 100644
index 00000000000000..c588fd8d94987f
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-copy-clause.c
@@ -0,0 +1,72 @@
+// 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 loop copy(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc serial loop copy(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc kernels loop copy(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-warning at +1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
+#pragma acc parallel loop pcopy(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-warning at +1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
+#pragma acc parallel loop present_or_copy(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // Valid cases:
+#pragma acc parallel loop copy(LocalInt, LocalPointer, LocalArray)
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copy(LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copy(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy(1 + IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy(+IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop copy(PointerParam[2:])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop copy(ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy((float*)ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy((float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC 'copy' clause is not valid on 'loop' directive}}
+#pragma acc loop copy(LocalInt)
+  for(int i = 5; i < 10;++i);
+  // expected-error at +1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}}
+#pragma acc loop pcopy(LocalInt)
+  for(int i = 5; i < 10;++i);
+  // expected-error at +1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}}
+#pragma acc loop present_or_copy(LocalInt)
+  for(int i = 5; i < 10;++i);
+}

diff  --git a/clang/test/SemaOpenACC/combined-construct-copy-clause.cpp b/clang/test/SemaOpenACC/combined-construct-copy-clause.cpp
new file mode 100644
index 00000000000000..043a7ec4dc0003
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-copy-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 loop copy(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc serial loop copy(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc kernels loop copy(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // Valid cases:
+#pragma acc parallel loop copy(LocalInt, LocalPointer, LocalArray)
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copy(LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+
+  Complete LocalComposite2;
+#pragma acc parallel loop copy(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy(1 + IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy(+IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop copy(PointerParam[2:])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop copy(ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy((float*)ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy((float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+}
+
+template<typename T, unsigned I, typename V>
+void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy(+t)
+  for(int i = 0; i < 5; ++i);
+
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#TEMPL_USES_INST{{in instantiation of}}
+#pragma acc parallel loop copy(I)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copy(t, I)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copy(arrayT)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copy(TemplComp)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copy(TemplComp.PointerMember[5])
+  for(int i = 0; i < 5; ++i);
+ int *Pointer;
+#pragma acc parallel loop copy(Pointer[:I])
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copy(Pointer[:t])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop copy(Pointer[1:])
+  for(int i = 0; i < 5; ++i);
+}
+
+template<unsigned I, auto &NTTP_REF>
+void NTTP() {
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#NTTP_INST{{in instantiation of}}
+#pragma acc parallel loop copy(I)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copy(NTTP_REF)
+  for(int i = 0; i < 5; ++i);
+}
+
+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/combined-construct-copyin-ast.cpp b/clang/test/SemaOpenACC/combined-construct-copyin-ast.cpp
new file mode 100644
index 00000000000000..e7ac8238a7db62
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-copyin-ast.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s
+
+// Test this with PCH.
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -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 parallel loop copyin(GlobalArray) pcopyin(readonly:PointerParam[Global]) present_or_copyin(Global)
+  for (unsigned i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: copyin clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
+  // CHECK-NEXT: pcopyin clause : readonly
+  // 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: present_or_copyin clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+}
+
+template<auto &NTTP, typename T, typename U>
+void TemplUses(T t, U u) {
+  // CHECK-NEXT: FunctionTemplateDecl
+  // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U
+  // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)'
+  // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
+  // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
+  // CHECK-NEXT: CompoundStmt
+
+#pragma acc parallel loop copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t])
+  for (unsigned i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: copyin clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+  // CHECK-NEXT: pcopyin clause : readonly
+  // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
+  // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
+  // CHECK-NEXT: present_or_copyin clause
+  // CHECK-NEXT: ArraySectionExpr
+  // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
+  // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
+  // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+
+  // Check the instantiated versions of the above.
+  // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation
+  // CHECK-NEXT: TemplateArgument decl
+  // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
+  // CHECK-NEXT: TemplateArgument type 'int'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: TemplateArgument type 'int *'
+  // CHECK-NEXT: PointerType{{.*}} 'int *'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
+  // CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *'
+  // CHECK-NEXT: CompoundStmt
+
+// #pragma acc parallel copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t])
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: copyin clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+  // CHECK-NEXT: pcopyin clause : readonly
+  // 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: present_or_copyin clause
+  // CHECK-NEXT: ArraySectionExpr
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
+  // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+}
+
+void Inst() {
+  static constexpr unsigned CEVar = 1;
+  int i;
+  TemplUses<CEVar>(i, &i);
+}
+#endif

diff  --git a/clang/test/SemaOpenACC/combined-construct-copyin-clause.c b/clang/test/SemaOpenACC/combined-construct-copyin-clause.c
new file mode 100644
index 00000000000000..4cb635ddb2470b
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-copyin-clause.c
@@ -0,0 +1,78 @@
+// 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 loop copyin(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc serial loop copyin(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc kernels loop copyin(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-warning at +1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
+#pragma acc parallel loop pcopyin(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
+#pragma acc parallel loop present_or_copyin(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // Valid cases:
+#pragma acc parallel loop copyin(LocalInt, LocalPointer, LocalArray)
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copyin(LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copyin(readonly:LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyin(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin(1 + IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin(+IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop copyin(PointerParam[2:])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop copyin(ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin((float*)ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin((float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +2{{invalid tag 'invalid' on 'copyin' clause}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin(invalid:(float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC 'copyin' clause is not valid on 'loop' directive}}
+#pragma acc loop copyin(LocalInt)
+  for(int i = 5; i < 10;++i);
+  // expected-error at +1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}}
+#pragma acc loop pcopyin(LocalInt)
+  for(int i = 5; i < 10;++i);
+  // expected-error at +1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}}
+#pragma acc loop present_or_copyin(LocalInt)
+  for(int i = 5; i < 10;++i);
+}

diff  --git a/clang/test/SemaOpenACC/combined-construct-copyin-clause.cpp b/clang/test/SemaOpenACC/combined-construct-copyin-clause.cpp
new file mode 100644
index 00000000000000..9f9c2aa641c43a
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-copyin-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 loop copyin(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc serial loop copyin(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc kernels loop copyin(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // Valid cases:
+#pragma acc parallel loop copyin(LocalInt, LocalPointer, LocalArray)
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copyin(LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+
+  Complete LocalComposite2;
+#pragma acc parallel loop copyin(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin(1 + IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin(+IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop copyin(PointerParam[2:])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop copyin(ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin((float*)ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin((float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+}
+
+template<typename T, unsigned I, typename V>
+void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin(+t)
+  for(int i = 0; i < 5; ++i);
+
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#TEMPL_USES_INST{{in instantiation of}}
+#pragma acc parallel loop copyin(I)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyin(t, I)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyin(arrayT)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyin(TemplComp)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyin(TemplComp.PointerMember[5])
+  for(int i = 0; i < 5; ++i);
+ int *Pointer;
+#pragma acc parallel loop copyin(Pointer[:I])
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copyin(Pointer[:t])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop copyin(Pointer[1:])
+  for(int i = 0; i < 5; ++i);
+}
+
+template<unsigned I, auto &NTTP_REF>
+void NTTP() {
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#NTTP_INST{{in instantiation of}}
+#pragma acc parallel loop copyin(I)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyin(NTTP_REF)
+  for(int i = 0; i < 5; ++i);
+}
+
+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/combined-construct-copyout-ast.cpp b/clang/test/SemaOpenACC/combined-construct-copyout-ast.cpp
new file mode 100644
index 00000000000000..02eda413dd53f9
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-copyout-ast.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s
+
+// Test this with PCH.
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -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 parallel loop copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(Global)
+  for (unsigned i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: copyout clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
+  // CHECK-NEXT: pcopyout clause : zero
+  // 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: present_or_copyout clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
+  // CHECK-NEXT: For
+  // CHECK: NullStmt
+}
+
+template<auto &NTTP, typename T, typename U>
+void TemplUses(T t, U u) {
+  // CHECK-NEXT: FunctionTemplateDecl
+  // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U
+  // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)'
+  // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
+  // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
+  // CHECK-NEXT: CompoundStmt
+
+#pragma acc parallel loop copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t])
+  for (unsigned i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: copyout clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+  // CHECK-NEXT: pcopyout clause : zero
+  // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
+  // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
+  // CHECK-NEXT: present_or_copyout clause
+  // CHECK-NEXT: ArraySectionExpr
+  // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
+  // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
+  // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+
+  // Check the instantiated versions of the above.
+  // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation
+  // CHECK-NEXT: TemplateArgument decl
+  // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
+  // CHECK-NEXT: TemplateArgument type 'int'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: TemplateArgument type 'int *'
+  // CHECK-NEXT: PointerType{{.*}} 'int *'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
+  // CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *'
+  // CHECK-NEXT: CompoundStmt
+
+// #pragma acc parallel copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t])
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: copyout clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+  // CHECK-NEXT: pcopyout clause : zero
+  // 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: present_or_copyout clause
+  // CHECK-NEXT: ArraySectionExpr
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
+  // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+}
+
+void Inst() {
+  static constexpr unsigned CEVar = 1;
+  int i;
+  TemplUses<CEVar>(i, &i);
+}
+#endif

diff  --git a/clang/test/SemaOpenACC/combined-construct-copyout-clause.c b/clang/test/SemaOpenACC/combined-construct-copyout-clause.c
new file mode 100644
index 00000000000000..c43f9592062fae
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-copyout-clause.c
@@ -0,0 +1,78 @@
+// 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 loop copyout(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc serial loop copyout(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc kernels loop copyout(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-warning at +1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
+#pragma acc parallel loop pcopyout(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-warning at +1{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
+#pragma acc parallel loop present_or_copyout(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // Valid cases:
+#pragma acc parallel loop copyout(LocalInt, LocalPointer, LocalArray)
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copyout(LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copyout(zero:LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyout(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout(1 + IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout(+IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop copyout(PointerParam[2:])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop copyout(ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout((float*)ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout((float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +2{{invalid tag 'invalid' on 'copyout' clause}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout(invalid:(float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC 'copyout' clause is not valid on 'loop' directive}}
+#pragma acc loop copyout(LocalInt)
+  for(int i = 0; i < 6;++i);
+  // expected-error at +1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}}
+#pragma acc loop pcopyout(LocalInt)
+  for(int i = 0; i < 6;++i);
+  // expected-error at +1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}}
+#pragma acc loop present_or_copyout(LocalInt)
+  for(int i = 0; i < 6;++i);
+}

diff  --git a/clang/test/SemaOpenACC/combined-construct-copyout-clause.cpp b/clang/test/SemaOpenACC/combined-construct-copyout-clause.cpp
new file mode 100644
index 00000000000000..cc91ea4d24986d
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-copyout-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 loop copyout(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc serial loop copyout(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc kernels loop copyout(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // Valid cases:
+#pragma acc parallel loop copyout(LocalInt, LocalPointer, LocalArray)
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copyout(LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+
+  Complete LocalComposite2;
+#pragma acc parallel loop copyout(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout(1 + IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout(+IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop copyout(PointerParam[2:])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop copyout(ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout((float*)ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout((float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+}
+
+template<typename T, unsigned I, typename V>
+void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout(+t)
+  for(int i = 0; i < 5; ++i);
+
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#TEMPL_USES_INST{{in instantiation of}}
+#pragma acc parallel loop copyout(I)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop copyout(t, I)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyout(arrayT)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyout(TemplComp)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyout(TemplComp.PointerMember[5])
+  for(int i = 0; i < 5; ++i);
+ int *Pointer;
+#pragma acc parallel loop copyout(Pointer[:I])
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop copyout(Pointer[:t])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop copyout(Pointer[1:])
+  for(int i = 0; i < 5; ++i);
+}
+
+template<unsigned I, auto &NTTP_REF>
+void NTTP() {
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#NTTP_INST{{in instantiation of}}
+#pragma acc parallel loop copyout(I)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop copyout(NTTP_REF)
+  for(int i = 0; i < 5; ++i);
+}
+
+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/combined-construct-create-ast.cpp b/clang/test/SemaOpenACC/combined-construct-create-ast.cpp
new file mode 100644
index 00000000000000..16268eda4e5d22
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-create-ast.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s
+
+// Test this with PCH.
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s
+// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -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 parallel loop create(GlobalArray) pcreate(zero:PointerParam[Global]) present_or_create(Global)
+  for (unsigned i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: create clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
+  // CHECK-NEXT: pcreate clause : zero
+  // 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: present_or_create clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+}
+
+template<auto &NTTP, typename T, typename U>
+void TemplUses(T t, U u) {
+  // CHECK-NEXT: FunctionTemplateDecl
+  // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U
+  // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)'
+  // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
+  // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
+  // CHECK-NEXT: CompoundStmt
+
+#pragma acc parallel loop create(t) pcreate(zero: NTTP, u) present_or_create(u[0:t])
+  for (unsigned i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: create clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+  // CHECK-NEXT: pcreate clause : zero
+  // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
+  // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
+  // CHECK-NEXT: present_or_create clause
+  // CHECK-NEXT: ArraySectionExpr
+  // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
+  // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
+  // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+
+  // Check the instantiated versions of the above.
+  // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation
+  // CHECK-NEXT: TemplateArgument decl
+  // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
+  // CHECK-NEXT: TemplateArgument type 'int'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: TemplateArgument type 'int *'
+  // CHECK-NEXT: PointerType{{.*}} 'int *'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
+  // CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *'
+  // CHECK-NEXT: CompoundStmt
+
+// #pragma acc parallel create(t) pcreate(zero: NTTP, u) present_or_create(u[0:t])
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: create clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+  // CHECK-NEXT: pcreate clause : zero
+  // 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: present_or_create clause
+  // CHECK-NEXT: ArraySectionExpr
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
+  // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+}
+
+void Inst() {
+  static constexpr unsigned CEVar = 1;
+  int i;
+  TemplUses<CEVar>(i, &i);
+}
+#endif

diff  --git a/clang/test/SemaOpenACC/combined-construct-create-clause.c b/clang/test/SemaOpenACC/combined-construct-create-clause.c
new file mode 100644
index 00000000000000..c17e6921a7da20
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-create-clause.c
@@ -0,0 +1,78 @@
+// 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 loop create(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc serial loop create(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc kernels loop create(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-warning at +1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
+#pragma acc parallel loop pcreate(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-warning at +1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
+#pragma acc parallel loop present_or_create(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // Valid cases:
+#pragma acc parallel loop create(LocalInt, LocalPointer, LocalArray)
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop create(LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop create(zero:LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop create(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create(1 + IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create(+IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop create(PointerParam[2:])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop create(ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create((float*)ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create((float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +2{{invalid tag 'invalid' on 'create' clause}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create(invalid:(float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC 'create' clause is not valid on 'loop' directive}}
+#pragma acc loop create(LocalInt)
+  for(int i = 5; i < 10;++i);
+  // expected-error at +1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}}
+#pragma acc loop pcreate(LocalInt)
+  for(int i = 5; i < 10;++i);
+  // expected-error at +1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}}
+#pragma acc loop present_or_create(LocalInt)
+  for(int i = 5; i < 10;++i);
+}

diff  --git a/clang/test/SemaOpenACC/combined-construct-create-clause.cpp b/clang/test/SemaOpenACC/combined-construct-create-clause.cpp
new file mode 100644
index 00000000000000..0c8f90eab3d087
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-create-clause.cpp
@@ -0,0 +1,113 @@
+
+// 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 loop create(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc serial loop create(LocalInt)
+  for(int i = 0; i < 5; ++i);
+#pragma acc kernels loop create(LocalInt)
+  for(int i = 0; i < 5; ++i);
+
+  // Valid cases:
+#pragma acc parallel loop create(LocalInt, LocalPointer, LocalArray)
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop create(LocalArray[2:1])
+  for(int i = 0; i < 5; ++i);
+
+  Complete LocalComposite2;
+#pragma acc parallel loop create(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create(1 + IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create(+IntParam)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop create(PointerParam[2:])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop create(ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create((float*)ArrayParam[2:5])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create((float)ArrayParam[2])
+  for(int i = 0; i < 5; ++i);
+}
+
+template<typename T, unsigned I, typename V>
+void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create(+t)
+  for(int i = 0; i < 5; ++i);
+
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#TEMPL_USES_INST{{in instantiation of}}
+#pragma acc parallel loop create(I)
+  for(int i = 0; i < 5; ++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop create(t, I)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop create(arrayT)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop create(TemplComp)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop create(TemplComp.PointerMember[5])
+  for(int i = 0; i < 5; ++i);
+ int *Pointer;
+#pragma acc parallel loop create(Pointer[:I])
+  for(int i = 0; i < 5; ++i);
+#pragma acc parallel loop create(Pointer[:t])
+  for(int i = 0; i < 5; ++i);
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop create(Pointer[1:])
+  for(int i = 0; i < 5; ++i);
+}
+
+template<unsigned I, auto &NTTP_REF>
+void NTTP() {
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#NTTP_INST{{in instantiation of}}
+#pragma acc parallel loop create(I)
+  for(int i = 0; i < 5; ++i);
+
+#pragma acc parallel loop create(NTTP_REF)
+  for(int i = 0; i < 5; ++i);
+}
+
+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/combined-construct-default-clause.c b/clang/test/SemaOpenACC/combined-construct-default-clause.c
index c420c8ebeb31d6..a9c90240cb1222 100644
--- a/clang/test/SemaOpenACC/combined-construct-default-clause.c
+++ b/clang/test/SemaOpenACC/combined-construct-default-clause.c
@@ -11,13 +11,11 @@ void SingleOnly() {
 
   int i;
 
-  // expected-warning at +3{{OpenACC clause 'copy' not yet implemented}}
   // expected-error at +2{{OpenACC 'default' clause cannot appear more than once on a 'kernels loop' directive}}
   // expected-note at +1{{previous clause is here}}
   #pragma acc kernels loop self default(present) present(i) default(none) copy(i)
   for(int i = 5; i < 10;++i);
 
-  // expected-warning at +3{{OpenACC clause 'copy' not yet implemented}}
   // expected-error at +2{{OpenACC 'default' clause cannot appear more than once on a 'parallel loop' directive}}
   // expected-note at +1{{previous clause is here}}
   #pragma acc parallel loop self default(present) private(i) default(none) copy(i)

diff  --git a/clang/test/SemaOpenACC/combined-construct-default-clause.cpp b/clang/test/SemaOpenACC/combined-construct-default-clause.cpp
index 70c9a7cb478133..60c4d21712e68f 100644
--- a/clang/test/SemaOpenACC/combined-construct-default-clause.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-default-clause.cpp
@@ -12,19 +12,16 @@ void SingleOnly() {
   #pragma acc parallel loop default(present) async default(none)
   for (unsigned I = 0; I < 5; ++I);
 
-  // expected-warning at +3{{OpenACC clause 'copy' not yet implemented, clause ignored}}
   // expected-error at +2{{OpenACC 'default' clause cannot appear more than once on a 'serial loop' directive}}
   // expected-note at +1{{previous clause is here}}
   #pragma acc serial loop async default(present) copy(i) default(none) self
   for (unsigned I = 0; I < 5; ++I);
 
-  // expected-warning at +3{{OpenACC clause 'copy' not yet implemented, clause ignored}}
   // expected-error at +2{{OpenACC 'default' clause cannot appear more than once on a 'kernels loop' directive}}
   // expected-note at +1{{previous clause is here}}
   #pragma acc kernels loop async default(present) copy(i) default(none) self
   for (unsigned I = 0; I < 5; ++I);
 
-  // expected-warning at +2{{OpenACC clause 'copy' not yet implemented, clause ignored}}
   // expected-error at +1{{expected '('}}
   #pragma acc parallel loop async default(none) copy(i) default self
   for (unsigned I = 0; I < 5; ++I);

diff  --git a/clang/test/SemaOpenACC/compute-construct-default-clause.c b/clang/test/SemaOpenACC/compute-construct-default-clause.c
index e71fee47e8a292..70e29f3e8ac051 100644
--- a/clang/test/SemaOpenACC/compute-construct-default-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-default-clause.c
@@ -16,17 +16,16 @@ void SingleOnly() {
   #pragma acc kernels self default(present) present(i) default(none) copy(i)
   while(0);
 
-  // expected-warning at +3{{OpenACC clause 'copy' not yet implemented}}
-  // expected-error at +2{{OpenACC 'default' clause cannot appear more than once on a 'parallel loop' directive}}
+  // expected-error at +2{{OpenACC 'default' clause cannot appear more than once on a 'parallel' directive}}
   // expected-note at +1{{previous clause is here}}
-  #pragma acc parallel loop self default(present) private(i) default(none) copy(i)
+  #pragma acc parallel self default(present) private(i) default(none) copy(i)
   for(int i = 0; i < 5; ++i);
 
   // expected-error at +1{{expected '('}}
-  #pragma acc serial loop self default private(i) default(none) if(i)
+  #pragma acc serial self default private(i) default(none) if(i)
   for(int i = 0; i < 5; ++i);
 
-  #pragma acc kernels loop default(none)
+  #pragma acc kernels default(none)
   for(int i = 0; i < 5; ++i);
 
   // expected-warning at +2{{OpenACC construct 'data' not yet implemented}}


        


More information about the cfe-commits mailing list