[clang] [OpenACC] Implement compound construct parsing (PR #72692)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 17 13:36:09 PST 2023


https://github.com/erichkeane updated https://github.com/llvm/llvm-project/pull/72692

>From 33ca88871b48fcfb16bdf7fa636a9ecfa4f38e08 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Fri, 17 Nov 2023 11:34:43 -0800
Subject: [PATCH 1/2] [OpenACC] Implement compound construct parsing

This patch implements the compound construct parsing, which allows
'parallel loop', 'serial loop', and 'kernel loop' to act as their own
constructs.

Note that this doesn't end up making any changes to the tests, as
previously these ended up being considered clauses, which are also not
implemented. However, the location of that diagnostic is now 1 token
further along.
---
 clang/include/clang/Basic/OpenACCKinds.h |  5 +++-
 clang/lib/Parse/ParseOpenACC.cpp         | 33 +++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index 8da02b93b2b974c..d53b7223b5334b3 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -33,7 +33,10 @@ enum class OpenACCDirectiveKind {
   Loop,
   // FIXME: 'cache'
 
-  // FIXME: Combined Constructs.
+  // Combined Constructs.
+  ParallelLoop,
+  SerialLoop,
+  KernelsLoop,
 
   // FIXME: atomic Construct variants.
 
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index ba29d75fe35a500..a3c802b1f829877 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -22,7 +22,9 @@ using namespace llvm;
 
 namespace {
 
-// Translate single-token string representations to the OpenACC Directive Kind.
+// This doesn't completely comprehend 'Compound Constructs' (as it just
+// identifies the first token) just the first token of each.  So
+// this should only be used by `ParseOpenACCDirectiveKind`.
 OpenACCDirectiveKind GetOpenACCDirectiveKind(StringRef Name) {
   return llvm::StringSwitch<OpenACCDirectiveKind>(Name)
       .Case("parallel", OpenACCDirectiveKind::Parallel)
@@ -50,6 +52,35 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
   if (DirKind == OpenACCDirectiveKind::Invalid)
     P.Diag(FirstTok, diag::err_acc_invalid_directive) << FirstTokSpelling;
 
+  // Combined Constructs allows parallel loop, serial loop, or kernels loop. Any
+  // other attempt at a combined construct will be diagnosed as an invalid
+  // clause.
+  Token SecondTok = P.getCurToken();
+  switch (DirKind) {
+  default:
+    // Nothing to do except in the below cases, as they should be diagnosed as
+    // a clause.
+    break;
+  case OpenACCDirectiveKind::Parallel:
+    if (P.getPreprocessor().getSpelling(SecondTok) == "loop") {
+      P.ConsumeToken();
+      return OpenACCDirectiveKind::ParallelLoop;
+    }
+    break;
+  case OpenACCDirectiveKind::Serial:
+    if (P.getPreprocessor().getSpelling(SecondTok) == "loop") {
+      P.ConsumeToken();
+      return OpenACCDirectiveKind::SerialLoop;
+    }
+    break;
+  case OpenACCDirectiveKind::Kernels:
+    if (P.getPreprocessor().getSpelling(SecondTok) == "loop") {
+      P.ConsumeToken();
+      return OpenACCDirectiveKind::KernelsLoop;
+    }
+    break;
+  }
+
   return DirKind;
 }
 

>From bb2020318ec35858293f4c7a42e3fb2904a3013f Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Fri, 17 Nov 2023 13:35:53 -0800
Subject: [PATCH 2/2] Fix Alexeys comments

---
 clang/lib/Parse/ParseOpenACC.cpp | 48 +++++++++++++++-----------------
 1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index a3c802b1f829877..7a29c825c146f6b 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -22,10 +22,10 @@ using namespace llvm;
 
 namespace {
 
-// This doesn't completely comprehend 'Compound Constructs' (as it just
-// identifies the first token) just the first token of each.  So
-// this should only be used by `ParseOpenACCDirectiveKind`.
-OpenACCDirectiveKind GetOpenACCDirectiveKind(StringRef Name) {
+/// This doesn't completely comprehend 'Compound Constructs' (as it just
+/// identifies the first token) just the first token of each.  So
+/// this should only be used by `ParseOpenACCDirectiveKind`.
+OpenACCDirectiveKind getOpenACCDirectiveKind(StringRef Name) {
   return llvm::StringSwitch<OpenACCDirectiveKind>(Name)
       .Case("parallel", OpenACCDirectiveKind::Parallel)
       .Case("serial", OpenACCDirectiveKind::Serial)
@@ -47,7 +47,7 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
   P.ConsumeToken();
   std::string FirstTokSpelling = P.getPreprocessor().getSpelling(FirstTok);
 
-  OpenACCDirectiveKind DirKind = GetOpenACCDirectiveKind(FirstTokSpelling);
+  OpenACCDirectiveKind DirKind = getOpenACCDirectiveKind(FirstTokSpelling);
 
   if (DirKind == OpenACCDirectiveKind::Invalid)
     P.Diag(FirstTok, diag::err_acc_invalid_directive) << FirstTokSpelling;
@@ -56,29 +56,25 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
   // other attempt at a combined construct will be diagnosed as an invalid
   // clause.
   Token SecondTok = P.getCurToken();
-  switch (DirKind) {
-  default:
-    // Nothing to do except in the below cases, as they should be diagnosed as
-    // a clause.
-    break;
-  case OpenACCDirectiveKind::Parallel:
-    if (P.getPreprocessor().getSpelling(SecondTok) == "loop") {
+  if (!SecondTok.isAnnotation() &&
+      P.getPreprocessor().getSpelling(SecondTok) == "loop") {
+    OpenACCDirectiveKind ReturnKind;
+    switch (DirKind) {
+    default:
+      // Nothing to do except in the below cases, as they should be diagnosed as
+      // a clause.
+      break;
+    case OpenACCDirectiveKind::Parallel:
+      ReturnKind = OpenACCDirectiveKind::ParallelLoop;
+      LLVM_FALLTHROUGH;
+    case OpenACCDirectiveKind::Serial:
+      ReturnKind = OpenACCDirectiveKind::SerialLoop;
+      LLVM_FALLTHROUGH;
+    case OpenACCDirectiveKind::Kernels:
+      ReturnKind = OpenACCDirectiveKind::KernelsLoop;
       P.ConsumeToken();
-      return OpenACCDirectiveKind::ParallelLoop;
+      return ReturnKind;
     }
-    break;
-  case OpenACCDirectiveKind::Serial:
-    if (P.getPreprocessor().getSpelling(SecondTok) == "loop") {
-      P.ConsumeToken();
-      return OpenACCDirectiveKind::SerialLoop;
-    }
-    break;
-  case OpenACCDirectiveKind::Kernels:
-    if (P.getPreprocessor().getSpelling(SecondTok) == "loop") {
-      P.ConsumeToken();
-      return OpenACCDirectiveKind::KernelsLoop;
-    }
-    break;
   }
 
   return DirKind;



More information about the cfe-commits mailing list