================ @@ -0,0 +1,140 @@ +//===- StmtOpenACC.h - Classes for OpenACC directives ----------*- C++ -*-===// +// +// 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 defines OpenACC AST classes for statement-level contructs. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_STMTOPENACC_H +#define LLVM_CLANG_AST_STMTOPENACC_H + +#include "clang/AST/Stmt.h" +#include "clang/Basic/OpenACCKinds.h" +#include "clang/Basic/SourceLocation.h" + +namespace clang { +/// This is the base class for an OpenACC statement-level construct, other +/// construct types are expected to inherit from this. +class OpenACCConstructStmt : public Stmt { + friend class ASTStmtWriter; + friend class ASTStmtReader; + /// The directive kind. Each implementation of this interface should handle + /// specific kinds. + OpenACCDirectiveKind Kind = OpenACCDirectiveKind::Invalid; + /// The location of the directive statement, from the '#' to the last token of + /// the directive. + SourceRange Range; + + // TODO OPENACC: Clauses should probably be collected in this class. + +protected: + OpenACCConstructStmt(StmtClass SC, OpenACCDirectiveKind K, + SourceLocation Start, SourceLocation End) + : Stmt(SC), Kind(K), Range(Start, End) {} + +public: + OpenACCDirectiveKind getDirectiveKind() const { return Kind; } + + static bool classof(const Stmt *S) { + return S->getStmtClass() >= firstOpenACCConstructStmtConstant && + S->getStmtClass() <= lastOpenACCConstructStmtConstant; + } + + SourceLocation getBeginLoc() const { return Range.getBegin(); } + SourceLocation getEndLoc() const { return Range.getEnd(); } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_cast<OpenACCConstructStmt *>(this)->children(); + } +}; + +/// This is a base class for any OpenACC statement-level constructs that have an +/// associated statement. This class is not intended to be instantiated, but is +/// a convenient place to hold the associated statement. +class OpenACCAssociatedStmtConstruct : public OpenACCConstructStmt { + friend class ASTStmtWriter; + friend class ASTStmtReader; + template <typename Derived> friend class RecursiveASTVisitor; + Stmt *AssociatedStmt = nullptr; + +protected: + OpenACCAssociatedStmtConstruct(StmtClass SC, OpenACCDirectiveKind K, + SourceLocation Start, SourceLocation End) + : OpenACCConstructStmt(SC, K, Start, End) {} + + void setAssociatedStmt(Stmt *S) { AssociatedStmt = S; } + Stmt *getAssociatedStmt() { return AssociatedStmt; } + const Stmt *getAssociatedStmt() const { + return const_cast<OpenACCAssociatedStmtConstruct *>(this) + ->getAssociatedStmt(); + } + +public: + child_range children() { + if (getAssociatedStmt()) + return child_range(&AssociatedStmt, &AssociatedStmt + 1); + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_cast<OpenACCAssociatedStmtConstruct *>(this)->children(); + } +}; +/// This class represents a compute construct, representing a 'Kind' of +/// `parallel', 'serial', or 'kernel'. These constructs are associated with a +/// 'structured block', defined as: +/// +/// in C or C++, an executable statement, possibly compound, with a single +/// entry at the top and a single exit at the bottom +/// +/// At the moment there is no real motivation to have a different AST node for +/// those three, as they are semantically identical, and have only minor +/// differences in the permitted list of clauses, which can be differentiated by +/// the 'Kind'. +class OpenACCComputeConstruct : public OpenACCAssociatedStmtConstruct { + friend class ASTStmtWriter; + friend class ASTStmtReader; + OpenACCComputeConstruct() + : OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass, + OpenACCDirectiveKind::Invalid, + SourceLocation{}, SourceLocation{}) {} + + OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start, + SourceLocation End) + : OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass, K, Start, + End) { + assert((K == OpenACCDirectiveKind::Parallel || + K == OpenACCDirectiveKind::Serial || + K == OpenACCDirectiveKind::Kernels) && + "Only parallel, serial, and kernels constructs should be " + "represented by this type"); + } + +public: + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpenACCComputeConstructClass; + } + + static OpenACCComputeConstruct *CreateEmpty(const ASTContext &C, EmptyShell); + static OpenACCComputeConstruct *Create(const ASTContext &C, + OpenACCDirectiveKind K, + SourceLocation BeginLoc, + SourceLocation EndLoc); + + void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); } ---------------- alexey-bataev wrote:
Better to make it private/protected https://github.com/llvm/llvm-project/pull/81188 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits