[clang] [OpenACC][NFC] Implement basic OpenACC Sema infrastructure (PR #81874)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 15 09:05:12 PST 2024


https://github.com/erichkeane created https://github.com/llvm/llvm-project/pull/81874

This patch is split off from #81659, and contains just the Sema infrastructure that we can later use to implement semantic analysis of OpenACC constructs.

>From 35700522a658571e2abad279f327f4160fdb6c9d Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Thu, 15 Feb 2024 08:41:58 -0800
Subject: [PATCH] [OpenACC][NFC] Implement basic OpenACC Sema infrastructure

This patch is split off from #81659, and contains just the Sema
infrastructure that we can later use to implement semantic analysis of
OpenACC constructs.
---
 clang/include/clang/Parse/Parser.h | 16 +++++++++-
 clang/include/clang/Sema/Sema.h    | 41 ++++++++++++++++++++++++++
 clang/lib/Parse/ParseOpenACC.cpp   | 47 +++++++++++++++++++++++++-----
 clang/lib/Sema/CMakeLists.txt      |  1 +
 clang/lib/Sema/SemaOpenACC.cpp     | 47 ++++++++++++++++++++++++++++++
 5 files changed, 143 insertions(+), 9 deletions(-)
 create mode 100644 clang/lib/Sema/SemaOpenACC.cpp

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index da18cf88edcc92..69b9e837fe8bef 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3572,7 +3572,21 @@ class Parser : public CodeCompletionHandler {
   StmtResult ParseOpenACCDirectiveStmt();
 
 private:
-  void ParseOpenACCDirective();
+  /// A struct to hold the information that got parsed by ParseOpenACCDirective,
+  /// so that the callers of it can use that to construct the appropriate AST
+  /// nodes.
+  struct OpenACCDirectiveParseInfo {
+    OpenACCDirectiveKind DirKind;
+    SourceLocation StartLoc;
+    SourceLocation EndLoc;
+    // TODO OpenACC: Add Clause list here once we have a type for that.
+    // TODO OpenACC: As we implement support for the Atomic, Routine, Cache, and
+    // Wait constructs, we likely want to put that information in here as well.
+  };
+
+  /// Parses the OpenACC directive (the entire pragma) including the clause
+  /// list, but does not produce the main AST node.
+  OpenACCDirectiveParseInfo ParseOpenACCDirective();
   /// Helper that parses an ID Expression based on the language options.
   ExprResult ParseOpenACCIDExpression();
   /// Parses the variable list for the `cache` construct.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ed933f27f8df6b..ec4c451c584612 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -41,6 +41,7 @@
 #include "clang/Basic/DarwinSDKInfo.h"
 #include "clang/Basic/ExpressionTraits.h"
 #include "clang/Basic/Module.h"
+#include "clang/Basic/OpenACCKinds.h"
 #include "clang/Basic/OpenCLOptions.h"
 #include "clang/Basic/OpenMPKinds.h"
 #include "clang/Basic/PragmaKinds.h"
@@ -12704,6 +12705,46 @@ class Sema final {
   OMPClause *ActOnOpenMPXBareClause(SourceLocation StartLoc,
                                     SourceLocation EndLoc);
 
+  //===--------------------------------------------------------------------===//
+  // OpenACC directives and clauses.
+
+  /// Called after parsing an OpenACC Clause so that it can be checked.
+  bool ActOnOpenACCClause(OpenACCClauseKind ClauseKind,
+                          SourceLocation StartLoc);
+
+  /// Called after the construct has been parsed, but clauses haven't been
+  /// parsed.  This allows us to diagnose not-implemented, as well as set up any
+  /// state required for parsing the clauses.
+  void ActOnOpenACCConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc);
+
+  /// Called after the directive, including its clauses, have been parsed and
+  /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
+  /// happen before any associated declarations or statements have been parsed.
+  /// This function is only called when we are parsing a 'statement' context.
+  bool ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K,
+                                      SourceLocation StartLoc);
+
+  /// Called after the directive, including its clauses, have been parsed and
+  /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
+  /// happen before any associated declarations or statements have been parsed.
+  /// This function is only called when we are parsing a 'Decl' context.
+  bool ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K,
+                                      SourceLocation StartLoc);
+  /// Called when we encounter an associated statement for our construct, this
+  /// should check legality of the statement as it appertains to this Construct.
+  StmtResult ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
+                                        StmtResult AssocStmt);
+
+  /// Called after the directive has been completely parsed, including the
+  /// declaration group or associated statement.
+  StmtResult ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
+                                          SourceLocation StartLoc,
+                                          SourceLocation EndLoc,
+                                          StmtResult AssocStmt);
+  /// Called after the directive has been completely parsed, including the
+  /// declaration group or associated statement.
+  DeclGroupRef ActOnEndOpenACCDeclDirective();
+
   /// The kind of conversion being performed.
   enum CheckedConversionKind {
     /// An implicit conversion.
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index e099d077198d09..93d98ca826ae22 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -550,6 +550,11 @@ void SkipUntilEndOfDirective(Parser &P) {
     P.ConsumeAnyToken();
 }
 
+bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) {
+  // TODO OpenACC: Implement.
+  return false;
+}
+
 } // namespace
 
 // OpenACC 3.3, section 1.7:
@@ -745,9 +750,11 @@ bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) {
            << getCurToken().getIdentifierInfo();
 
   // Consume the clause name.
-  ConsumeToken();
+  SourceLocation ClauseLoc = ConsumeToken();
 
-  return ParseOpenACCClauseParams(DirKind, Kind);
+  bool Result = ParseOpenACCClauseParams(DirKind, Kind);
+  getActions().ActOnOpenACCClause(Kind, ClauseLoc);
+  return Result;
 }
 
 bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
@@ -1116,9 +1123,12 @@ void Parser::ParseOpenACCCacheVarList() {
   }
 }
 
-void Parser::ParseOpenACCDirective() {
+Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() {
+  SourceLocation StartLoc = getCurToken().getLocation();
   OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this);
 
+  getActions().ActOnOpenACCConstruct(DirKind, StartLoc);
+
   // Once we've parsed the construct/directive name, some have additional
   // specifiers that need to be taken care of. Atomic has an 'atomic-clause'
   // that needs to be parsed.
@@ -1175,7 +1185,10 @@ void Parser::ParseOpenACCDirective() {
   Diag(getCurToken(), diag::warn_pragma_acc_unimplemented);
   assert(Tok.is(tok::annot_pragma_openacc_end) &&
          "Didn't parse all OpenACC Clauses");
-  ConsumeAnnotationToken();
+  SourceLocation EndLoc = ConsumeAnnotationToken();
+  assert(EndLoc.isValid());
+
+  return OpenACCDirectiveParseInfo{DirKind, StartLoc, EndLoc};
 }
 
 // Parse OpenACC directive on a declaration.
@@ -1185,9 +1198,14 @@ Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() {
   ParsingOpenACCDirectiveRAII DirScope(*this);
   ConsumeAnnotationToken();
 
-  ParseOpenACCDirective();
+  OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
+
+  if (getActions().ActOnStartOpenACCDeclDirective(DirInfo.DirKind,
+                                                  DirInfo.StartLoc))
+    return nullptr;
 
-  return nullptr;
+  // TODO OpenACC: Do whatever decl parsing is required here.
+  return DeclGroupPtrTy::make(getActions().ActOnEndOpenACCDeclDirective());
 }
 
 // Parse OpenACC Directive on a Statement.
@@ -1197,7 +1215,20 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() {
   ParsingOpenACCDirectiveRAII DirScope(*this);
   ConsumeAnnotationToken();
 
-  ParseOpenACCDirective();
+  OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
+  if (getActions().ActOnStartOpenACCDeclDirective(DirInfo.DirKind,
+                                                  DirInfo.StartLoc))
+    return StmtError();
+
+  StmtResult AssocStmt;
+
+  if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) {
+    ParsingOpenACCDirectiveRAII DirScope(*this, /*Value=*/false);
+    AssocStmt = getActions().ActOnOpenACCAssociatedStmt(DirInfo.DirKind,
+                                                        ParseStatement());
+  }
 
-  return StmtEmpty();
+  return getActions().ActOnEndOpenACCStmtDirective(
+      DirInfo.DirKind, DirInfo.StartLoc, DirInfo.EndLoc, AssocStmt);
 }
+:Xa
diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index 1856a88e9a3271..862f9d4ffb825d 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -52,6 +52,7 @@ add_clang_library(clangSema
   SemaLookup.cpp
   SemaModule.cpp
   SemaObjCProperty.cpp
+  SemaOpenACC.cpp
   SemaOpenMP.cpp
   SemaOverload.cpp
   SemaPseudoObject.cpp
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
new file mode 100644
index 00000000000000..dc530845433900
--- /dev/null
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -0,0 +1,47 @@
+//===--- SemaOpenACC.cpp - Semantic Analysis for OpenACC constructs -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements semantic analysis for OpenACC constructs and
+/// clauses.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/OpenACCKinds.h"
+#include "clang/Sema/Sema.h"
+
+using namespace clang;
+bool Sema::ActOnOpenACCClause(OpenACCClauseKind ClauseKind,
+                              SourceLocation StartLoc) {
+  return true;
+}
+void Sema::ActOnOpenACCConstruct(OpenACCDirectiveKind K,
+                                 SourceLocation StartLoc) {}
+
+bool Sema::ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K,
+                                          SourceLocation StartLoc) {
+  return true;
+}
+
+StmtResult Sema::ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
+                                              SourceLocation StartLoc,
+                                              SourceLocation EndLoc,
+                                              StmtResult AssocStmt) {
+  return StmtEmpty();
+}
+
+StmtResult Sema::ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
+                                            StmtResult AssocStmt) {
+  return AssocStmt;
+}
+
+bool Sema::ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K,
+                                          SourceLocation StartLoc) {
+  return true;
+}
+
+DeclGroupRef Sema::ActOnEndOpenACCDeclDirective() { return DeclGroupRef{}; }



More information about the cfe-commits mailing list