[clang] 2244d2e - [OpenACC] Implement 'if_present' clause sema

via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 13 13:05:02 PST 2024


Author: erichkeane
Date: 2024-12-13T13:04:57-08:00
New Revision: 2244d2e75c50cdd4657ed6c488423790367e1347

URL: https://github.com/llvm/llvm-project/commit/2244d2e75c50cdd4657ed6c488423790367e1347
DIFF: https://github.com/llvm/llvm-project/commit/2244d2e75c50cdd4657ed6c488423790367e1347.diff

LOG: [OpenACC] Implement 'if_present' clause sema

The 'if_present' clause controls the replacement of addresses in the
var-list in current device memory.  This clause can only go on
'host_device'.  From a Sema perspective, there isn't anything to do
beyond add this to AST and pass it on.

Added: 
    clang/test/SemaOpenACC/data-construct-if_present-ast.cpp
    clang/test/SemaOpenACC/data-construct-if_present-clause.c

Modified: 
    clang/include/clang/AST/OpenACCClause.h
    clang/include/clang/Basic/OpenACCClauses.def
    clang/lib/AST/OpenACCClause.cpp
    clang/lib/AST/StmtProfile.cpp
    clang/lib/AST/TextNodeDumper.cpp
    clang/lib/Sema/SemaOpenACC.cpp
    clang/lib/Sema/TreeTransform.h
    clang/lib/Serialization/ASTReader.cpp
    clang/lib/Serialization/ASTWriter.cpp
    clang/test/AST/ast-print-openacc-data-construct.cpp
    clang/test/ParserOpenACC/parse-clauses.c
    clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
    clang/test/SemaOpenACC/combined-construct-device_type-clause.c
    clang/test/SemaOpenACC/compute-construct-device_type-clause.c
    clang/test/SemaOpenACC/data-construct.cpp
    clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
    clang/test/SemaOpenACC/loop-construct-device_type-clause.c
    clang/tools/libclang/CIndex.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h
index 767ad1270ffbd9..57cd9a1e8564d2 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -98,6 +98,28 @@ class OpenACCFinalizeClause : public OpenACCClause {
   }
 };
 
+// Represents the 'if_present' clause.
+class OpenACCIfPresentClause : public OpenACCClause {
+protected:
+  OpenACCIfPresentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
+      : OpenACCClause(OpenACCClauseKind::IfPresent, BeginLoc, EndLoc) {}
+
+public:
+  static bool classof(const OpenACCClause *C) {
+    return C->getClauseKind() == OpenACCClauseKind::IfPresent;
+  }
+
+  static OpenACCIfPresentClause *
+  Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
+
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+};
+
 // Represents the 'independent' clause.
 class OpenACCIndependentClause : public OpenACCClause {
 protected:

diff  --git a/clang/include/clang/Basic/OpenACCClauses.def b/clang/include/clang/Basic/OpenACCClauses.def
index c3d536c33bc5b1..cc788e4de45279 100644
--- a/clang/include/clang/Basic/OpenACCClauses.def
+++ b/clang/include/clang/Basic/OpenACCClauses.def
@@ -45,6 +45,7 @@ VISIT_CLAUSE(Finalize)
 VISIT_CLAUSE(FirstPrivate)
 VISIT_CLAUSE(Gang)
 VISIT_CLAUSE(If)
+VISIT_CLAUSE(IfPresent)
 VISIT_CLAUSE(Independent)
 VISIT_CLAUSE(NoCreate)
 VISIT_CLAUSE(NumGangs)

diff  --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp
index 770f95f60b7b79..443cfa84474bed 100644
--- a/clang/lib/AST/OpenACCClause.cpp
+++ b/clang/lib/AST/OpenACCClause.cpp
@@ -452,6 +452,14 @@ OpenACCFinalizeClause *OpenACCFinalizeClause::Create(const ASTContext &C,
   return new (Mem) OpenACCFinalizeClause(BeginLoc, EndLoc);
 }
 
+OpenACCIfPresentClause *OpenACCIfPresentClause::Create(const ASTContext &C,
+                                                       SourceLocation BeginLoc,
+                                                       SourceLocation EndLoc) {
+  void *Mem = C.Allocate(sizeof(OpenACCIfPresentClause),
+                         alignof(OpenACCIfPresentClause));
+  return new (Mem) OpenACCIfPresentClause(BeginLoc, EndLoc);
+}
+
 //===----------------------------------------------------------------------===//
 //  OpenACC clauses printing methods
 //===----------------------------------------------------------------------===//
@@ -697,3 +705,8 @@ void OpenACCClausePrinter::VisitVectorClause(const OpenACCVectorClause &C) {
 void OpenACCClausePrinter::VisitFinalizeClause(const OpenACCFinalizeClause &C) {
   OS << "finalize";
 }
+
+void OpenACCClausePrinter::VisitIfPresentClause(
+    const OpenACCIfPresentClause &C) {
+  OS << "if_present";
+}

diff  --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 50418cf2d30e72..bd4956c15eea1c 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2561,6 +2561,9 @@ void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
 void OpenACCClauseProfiler::VisitFinalizeClause(
     const OpenACCFinalizeClause &Clause) {}
 
+void OpenACCClauseProfiler::VisitIfPresentClause(
+    const OpenACCIfPresentClause &Clause) {}
+
 void OpenACCClauseProfiler::VisitNumGangsClause(
     const OpenACCNumGangsClause &Clause) {
   for (auto *E : Clause.getIntExprs())

diff  --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 32e4569501d91f..0a5c0d561203af 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -409,6 +409,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
     case OpenACCClauseKind::PCopy:
     case OpenACCClauseKind::PresentOrCopy:
     case OpenACCClauseKind::If:
+    case OpenACCClauseKind::IfPresent:
     case OpenACCClauseKind::Independent:
     case OpenACCClauseKind::DevicePtr:
     case OpenACCClauseKind::Finalize:

diff  --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 8a002a17c1834c..3917c9bf60b8c4 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -416,6 +416,15 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
       return false;
     }
   }
+  case OpenACCClauseKind::IfPresent: {
+    switch (DirectiveKind) {
+    case OpenACCDirectiveKind::HostData:
+    case OpenACCDirectiveKind::Update:
+      return true;
+    default:
+      return false;
+    }
+  }
   }
 
   default:
@@ -1620,6 +1629,16 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(
                                        Clause.getEndLoc());
 }
 
+OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(
+    SemaOpenACC::OpenACCParsedClause &Clause) {
+  if (Clause.getDirectiveKind() != OpenACCDirectiveKind::HostData)
+    return isNotImplemented();
+  // There isn't anything to do here, this is only valid on one construct, and
+  // has no associated rules.
+  return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(),
+                                        Clause.getEndLoc());
+}
+
 OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(
     SemaOpenACC::OpenACCParsedClause &Clause) {
   // Restrictions only properly implemented on 'loop' constructs and combined ,

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 8ceebc398ab767..e5c3584b4d8820 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -11986,6 +11986,14 @@ void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
                                             ParsedClause.getEndLoc());
 }
 
+template <typename Derived>
+void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
+    const OpenACCIfPresentClause &C) {
+  NewClause = OpenACCIfPresentClause::Create(Self.getSema().getASTContext(),
+                                             ParsedClause.getBeginLoc(),
+                                             ParsedClause.getEndLoc());
+}
+
 template <typename Derived>
 void OpenACCClauseTransform<Derived>::VisitReductionClause(
     const OpenACCReductionClause &C) {

diff  --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index fd2dd1809fb1ae..4f7dc597d7bd5a 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -12536,6 +12536,8 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
     return OpenACCSeqClause::Create(getContext(), BeginLoc, EndLoc);
   case OpenACCClauseKind::Finalize:
     return OpenACCFinalizeClause::Create(getContext(), BeginLoc, EndLoc);
+  case OpenACCClauseKind::IfPresent:
+    return OpenACCIfPresentClause::Create(getContext(), BeginLoc, EndLoc);
   case OpenACCClauseKind::Independent:
     return OpenACCIndependentClause::Create(getContext(), BeginLoc, EndLoc);
   case OpenACCClauseKind::Auto:
@@ -12581,7 +12583,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
                                        VectorExpr, EndLoc);
   }
 
-  case OpenACCClauseKind::IfPresent:
   case OpenACCClauseKind::NoHost:
   case OpenACCClauseKind::UseDevice:
   case OpenACCClauseKind::Delete:

diff  --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index e11f2ac1f1191c..f263082cc13e9a 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -8452,6 +8452,7 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
   case OpenACCClauseKind::Independent:
   case OpenACCClauseKind::Auto:
   case OpenACCClauseKind::Finalize:
+  case OpenACCClauseKind::IfPresent:
     // Nothing to do here, there is no additional information beyond the
     // begin/end loc and clause kind.
     return;
@@ -8497,7 +8498,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
     return;
   }
 
-  case OpenACCClauseKind::IfPresent:
   case OpenACCClauseKind::NoHost:
   case OpenACCClauseKind::UseDevice:
   case OpenACCClauseKind::Delete:

diff  --git a/clang/test/AST/ast-print-openacc-data-construct.cpp b/clang/test/AST/ast-print-openacc-data-construct.cpp
index b1cd5f6b6fb96c..bcc68a18232598 100644
--- a/clang/test/AST/ast-print-openacc-data-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-data-construct.cpp
@@ -113,4 +113,8 @@ void foo() {
 
 // CHECK: #pragma acc exit data copyout(i) finalize
 #pragma acc exit data copyout(i) finalize
+
+// CHECK: #pragma acc host_data if_present
+#pragma acc host_data use_device(i) if_present
+  ;
 }

diff  --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index 3a08ef83385255..8003dad03c1c0d 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -16,11 +16,8 @@ void func() {
 
 #pragma acc exit data wait finalize
 
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented, clause ignored}}
 #pragma acc host_data if_present
 
-  // expected-warning at +2{{OpenACC clause 'if_present' not yet implemented, clause ignored}}
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented, clause ignored}}
 #pragma acc host_data if_present, if_present
 
   // expected-error at +4{{OpenACC clause 'independent' on 'loop' construct conflicts with previous data dependence clause}}

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 dfd8152b814d49..516658f8e01ff4 100644
--- a/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
+++ b/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
@@ -40,7 +40,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop auto finalize
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop auto if_present
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop auto worker
@@ -157,7 +157,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop finalize auto
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop if_present auto
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop worker auto
@@ -275,7 +275,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop independent finalize
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop independent if_present
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop independent worker
@@ -392,7 +392,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop finalize independent
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop if_present independent
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop worker independent
@@ -522,7 +522,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop seq finalize
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop seq if_present
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'nohost' not yet implemented}}
@@ -645,7 +645,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop finalize seq
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}}
 #pragma acc parallel loop if_present seq
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'nohost' not yet implemented}}

diff  --git a/clang/test/SemaOpenACC/combined-construct-device_type-clause.c b/clang/test/SemaOpenACC/combined-construct-device_type-clause.c
index ce6b8b8a4ea6d3..1a4bd94063e6c5 100644
--- a/clang/test/SemaOpenACC/combined-construct-device_type-clause.c
+++ b/clang/test/SemaOpenACC/combined-construct-device_type-clause.c
@@ -45,8 +45,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'serial loop' directive}}
 #pragma acc serial loop device_type(*) finalize
   for(int i = 0; i < 5; ++i);
-  // expected-error at +2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'kernels loop' construct}}
-  // expected-note at +1{{previous clause is here}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'kernels loop' directive}}
 #pragma acc kernels loop device_type(*) if_present
   for(int i = 0; i < 5; ++i);
 #pragma acc parallel loop device_type(*) seq

diff  --git a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c
index e2326336b748fa..dff8edb7f3dbfd 100644
--- a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c
@@ -45,8 +45,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'kernels' directive}}
 #pragma acc kernels device_type(*) finalize
   while(1);
-  // expected-error at +2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'kernels' construct}}
-  // expected-note at +1{{previous clause is here}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'kernels' directive}}
 #pragma acc kernels device_type(*) if_present
   while(1);
   // expected-error at +1{{OpenACC 'seq' clause is not valid on 'kernels' directive}}

diff  --git a/clang/test/SemaOpenACC/data-construct-if_present-ast.cpp b/clang/test/SemaOpenACC/data-construct-if_present-ast.cpp
new file mode 100644
index 00000000000000..d2ef6822819655
--- /dev/null
+++ b/clang/test/SemaOpenACC/data-construct-if_present-ast.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s
+
+// Test this with PCH.
+// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s
+// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s
+#ifndef PCH_HELPER
+#define PCH_HELPER
+
+void Uses() {
+  // CHECK: FunctionDecl{{.*}}Uses
+  // CHECK-NEXT: CompoundStmt
+
+  int I;
+  // CHECK-NEXT: DeclStmt
+  // CHECK-NEXT: VarDecl
+
+#pragma acc host_data use_device(I) if_present
+  ;
+  // CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data
+  // CHECK-NEXT: if_present clause
+  // CHECK-NEXT: NullStmt
+}
+
+template<typename T>
+void TemplUses() {
+  // CHECK: FunctionTemplateDecl{{.*}}TemplUses
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}T
+  // CHECK-NEXT: FunctionDecl{{.*}}TemplUses
+  // CHECK-NEXT: CompoundStmt
+
+  T I;
+  // CHECK-NEXT: DeclStmt
+  // CHECK-NEXT: VarDecl
+
+#pragma acc host_data use_device(I) if_present
+  ;
+  // CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data
+  // CHECK-NEXT: if_present clause
+  // CHECK-NEXT: NullStmt
+
+  // Instantiations
+  // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void ()' implicit_instantiation
+  // CHECK-NEXT: TemplateArgument type 'int'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: CompoundStmt
+
+  // CHECK-NEXT: DeclStmt
+  // CHECK-NEXT: VarDecl
+
+  // CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data
+  // CHECK-NEXT: if_present clause
+  // CHECK-NEXT: NullStmt
+}
+void Inst() {
+  TemplUses<int>();
+}
+
+
+#endif // PCH_HELPER

diff  --git a/clang/test/SemaOpenACC/data-construct-if_present-clause.c b/clang/test/SemaOpenACC/data-construct-if_present-clause.c
new file mode 100644
index 00000000000000..ce92ec024b4f99
--- /dev/null
+++ b/clang/test/SemaOpenACC/data-construct-if_present-clause.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+void Test() {
+  int I;
+
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'data' directive}}
+#pragma acc data copyin(I) if_present
+  ;
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'enter data' directive}}
+#pragma acc enter data copyin(I) if_present
+  ;
+
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'exit data' directive}}
+#pragma acc exit data copyout(I) if_present
+  ;
+  // expected-warning at +1{{OpenACC clause 'use_device' not yet implemented}}
+#pragma acc host_data use_device(I) if_present
+  ;
+}

diff  --git a/clang/test/SemaOpenACC/data-construct.cpp b/clang/test/SemaOpenACC/data-construct.cpp
index 3d345bc63d520e..0be88c7724e613 100644
--- a/clang/test/SemaOpenACC/data-construct.cpp
+++ b/clang/test/SemaOpenACC/data-construct.cpp
@@ -96,7 +96,6 @@ void AtLeastOneOf() {
 
 #pragma acc host_data if(Var)
   ;
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
 #pragma acc host_data if_present
   ;
 #pragma acc host_data

diff  --git a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
index dbb243869b8e21..a9ef1a03654a5a 100644
--- a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
+++ b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c
@@ -40,7 +40,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
 #pragma acc loop auto finalize
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
 #pragma acc loop auto if_present
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc loop auto worker
@@ -174,7 +174,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
 #pragma acc loop finalize auto
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
 #pragma acc loop if_present auto
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc loop worker auto
@@ -309,7 +309,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
 #pragma acc loop independent finalize
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
 #pragma acc loop independent if_present
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc loop independent worker
@@ -443,7 +443,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
 #pragma acc loop finalize independent
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
 #pragma acc loop if_present independent
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc loop worker independent
@@ -590,7 +590,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
 #pragma acc loop seq finalize
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
 #pragma acc loop seq if_present
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'nohost' not yet implemented}}
@@ -730,7 +730,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
 #pragma acc loop finalize seq
   for(unsigned i = 0; i < 5; ++i);
-  // expected-warning at +1{{OpenACC clause 'if_present' not yet implemented}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
 #pragma acc loop if_present seq
   for(unsigned i = 0; i < 5; ++i);
   // expected-warning at +1{{OpenACC clause 'nohost' not yet implemented}}

diff  --git a/clang/test/SemaOpenACC/loop-construct-device_type-clause.c b/clang/test/SemaOpenACC/loop-construct-device_type-clause.c
index 09c4d12b24a52a..ad572ad75bca65 100644
--- a/clang/test/SemaOpenACC/loop-construct-device_type-clause.c
+++ b/clang/test/SemaOpenACC/loop-construct-device_type-clause.c
@@ -44,8 +44,7 @@ void uses() {
   // expected-error at +1{{OpenACC 'finalize' clause is not valid on 'loop' directive}}
 #pragma acc loop device_type(*) finalize
   for(int i = 0; i < 5; ++i);
-  // expected-error at +2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'loop' construct}}
-  // expected-note at +1{{previous clause is here}}
+  // expected-error at +1{{OpenACC 'if_present' clause is not valid on 'loop' directive}}
 #pragma acc loop device_type(*) if_present
   for(int i = 0; i < 5; ++i);
 #pragma acc loop device_type(*) seq

diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 611b73cb1330b1..c5fdb9065a1c7a 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2923,6 +2923,8 @@ void OpenACCClauseEnqueue::VisitIndependentClause(
 void OpenACCClauseEnqueue::VisitSeqClause(const OpenACCSeqClause &C) {}
 void OpenACCClauseEnqueue::VisitFinalizeClause(const OpenACCFinalizeClause &C) {
 }
+void OpenACCClauseEnqueue::VisitIfPresentClause(
+    const OpenACCIfPresentClause &C) {}
 void OpenACCClauseEnqueue::VisitCollapseClause(const OpenACCCollapseClause &C) {
   Visitor.AddStmt(C.getLoopCount());
 }


        


More information about the cfe-commits mailing list