//===- DeclOpenMP.h - Classes for representing OpenMP 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 OpenMP nodes for declarative directives.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_DECLOPENMP_H
#define LLVM_CLANG_AST_DECLOPENMP_H

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/TrailingObjects.h"

namespace clang {

/// This is a basic class for representing single OpenMP declarative directive.
///
template <typename U> class OMPDeclarativeDirective : public U {
  friend class ASTDeclReader;
  friend class ASTDeclWriter;

  /// Get the clauses storage.
  MutableArrayRef<OMPClause *> getClauses() {
    if (!Data)
      return llvm::None;
    return Data->getClauses();
  }

protected:
  /// Data, associated with the directive.
  OMPChildren *Data = nullptr;

  /// Build instance of directive.
  template <typename... Params>
  OMPDeclarativeDirective(Params &&... P) : U(std::forward<Params>(P)...) {}

  template <typename T, typename... Params>
  static T *createDirective(const ASTContext &C, DeclContext *DC,
                            ArrayRef<OMPClause *> Clauses, unsigned NumChildren,
                            Params &&... P) {
    auto *Inst = new (C, DC, size(Clauses.size(), NumChildren))
        T(DC, std::forward<Params>(P)...);
    Inst->Data = OMPChildren::Create(Inst + 1, Clauses,
                                     /*AssociatedStmt=*/nullptr, NumChildren);
    Inst->Data->setClauses(Clauses);
    return Inst;
  }

  template <typename T, typename... Params>
  static T *createEmptyDirective(const ASTContext &C, unsigned ID,
                                 unsigned NumClauses, unsigned NumChildren,
                                 Params &&... P) {
    auto *Inst = new (C, ID, size(NumClauses, NumChildren))
        T(nullptr, std::forward<Params>(P)...);
    Inst->Data = OMPChildren::CreateEmpty(
        Inst + 1, NumClauses, /*HasAssociatedStmt=*/false, NumChildren);
    return Inst;
  }

  static size_t size(unsigned NumClauses, unsigned NumChildren) {
    return OMPChildren::size(NumClauses, /*HasAssociatedStmt=*/false,
                             NumChildren);
  }

public:
  /// Get number of clauses.
  unsigned getNumClauses() const {
    if (!Data)
      return 0;
    return Data->getNumClauses();
  }

  /// Returns specified clause.
  ///
  /// \param I Number of clause.
  ///
  OMPClause *getClause(unsigned I) const { return clauses()[I]; }

  ArrayRef<OMPClause *> clauses() const {
    if (!Data)
      return llvm::None;
    return Data->getClauses();
  }
};

/// This represents '#pragma omp threadprivate ...' directive.
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
///
/// \code
/// int a;
/// #pragma omp threadprivate(a)
/// struct A {
///   static int b;
/// #pragma omp threadprivate(b)
/// };
/// \endcode
///
class OMPThreadPrivateDecl final : public OMPDeclarativeDirective<Decl> {
  friend class OMPDeclarativeDirective<Decl>;

  virtual void anchor();

  OMPThreadPrivateDecl(DeclContext *DC = nullptr,
                       SourceLocation L = SourceLocation())
      : OMPDeclarativeDirective<Decl>(OMPThreadPrivate, DC, L) {}

  ArrayRef<const Expr *> getVars() const {
    auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
    return llvm::makeArrayRef(Storage, Data->getNumChildren());
  }

  MutableArrayRef<Expr *> getVars() {
    auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
    return llvm::makeMutableArrayRef(Storage, Data->getNumChildren());
  }

  void setVars(ArrayRef<Expr *> VL);

public:
  static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
                                      SourceLocation L,
                                      ArrayRef<Expr *> VL);
  static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
                                                  unsigned ID, unsigned N);

  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
  typedef llvm::iterator_range<varlist_iterator> varlist_range;
  typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;

  unsigned varlist_size() const { return Data->getNumChildren(); }
  bool varlist_empty() const { return Data->getChildren().empty(); }

  varlist_range varlists() {
    return varlist_range(varlist_begin(), varlist_end());
  }
  varlist_const_range varlists() const {
    return varlist_const_range(varlist_begin(), varlist_end());
  }
  varlist_iterator varlist_begin() { return getVars().begin(); }
  varlist_iterator varlist_end() { return getVars().end(); }
  varlist_const_iterator varlist_begin() const { return getVars().begin(); }
  varlist_const_iterator varlist_end() const { return getVars().end(); }

  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
};

/// This represents '#pragma omp declare reduction ...' directive.
/// For example, in the following, declared reduction 'foo' for types 'int' and
/// 'float':
///
/// \code
/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \
///                     initializer (omp_priv = 0)
/// \endcode
///
/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
  // This class stores some data in DeclContext::OMPDeclareReductionDeclBits
  // to save some space. Use the provided accessors to access it.
public:
  enum InitKind {
    CallInit,   // Initialized by function call.
    DirectInit, // omp_priv(<expr>)
    CopyInit    // omp_priv = <expr>
  };

private:
  friend class ASTDeclReader;
  /// Combiner for declare reduction construct.
  Expr *Combiner = nullptr;
  /// Initializer for declare reduction construct.
  Expr *Initializer = nullptr;
  /// In parameter of the combiner.
  Expr *In = nullptr;
  /// Out parameter of the combiner.
  Expr *Out = nullptr;
  /// Priv parameter of the initializer.
  Expr *Priv = nullptr;
  /// Orig parameter of the initializer.
  Expr *Orig = nullptr;

  /// Reference to the previous declare reduction construct in the same
  /// scope with the same name. Required for proper templates instantiation if
  /// the declare reduction construct is declared inside compound statement.
  LazyDeclPtr PrevDeclInScope;

  void anchor() override;

  OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
                          DeclarationName Name, QualType Ty,
                          OMPDeclareReductionDecl *PrevDeclInScope);

  void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
    PrevDeclInScope = Prev;
  }

public:
  /// Create declare reduction node.
  static OMPDeclareReductionDecl *
  Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
         QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
  /// Create deserialized declare reduction node.
  static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
                                                     unsigned ID);

  /// Get combiner expression of the declare reduction construct.
  Expr *getCombiner() { return Combiner; }
  const Expr *getCombiner() const { return Combiner; }
  /// Get In variable of the combiner.
  Expr *getCombinerIn() { return In; }
  const Expr *getCombinerIn() const { return In; }
  /// Get Out variable of the combiner.
  Expr *getCombinerOut() { return Out; }
  const Expr *getCombinerOut() const { return Out; }
  /// Set combiner expression for the declare reduction construct.
  void setCombiner(Expr *E) { Combiner = E; }
  /// Set combiner In and Out vars.
  void setCombinerData(Expr *InE, Expr *OutE) {
    In = InE;
    Out = OutE;
  }

  /// Get initializer expression (if specified) of the declare reduction
  /// construct.
  Expr *getInitializer() { return Initializer; }
  const Expr *getInitializer() const { return Initializer; }
  /// Get initializer kind.
  InitKind getInitializerKind() const {
    return static_cast<InitKind>(OMPDeclareReductionDeclBits.InitializerKind);
  }
  /// Get Orig variable of the initializer.
  Expr *getInitOrig() { return Orig; }
  const Expr *getInitOrig() const { return Orig; }
  /// Get Priv variable of the initializer.
  Expr *getInitPriv() { return Priv; }
  const Expr *getInitPriv() const { return Priv; }
  /// Set initializer expression for the declare reduction construct.
  void setInitializer(Expr *E, InitKind IK) {
    Initializer = E;
    OMPDeclareReductionDeclBits.InitializerKind = IK;
  }
  /// Set initializer Orig and Priv vars.
  void setInitializerData(Expr *OrigE, Expr *PrivE) {
    Orig = OrigE;
    Priv = PrivE;
  }

  /// Get reference to previous declare reduction construct in the same
  /// scope with the same name.
  OMPDeclareReductionDecl *getPrevDeclInScope();
  const OMPDeclareReductionDecl *getPrevDeclInScope() const;

  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
  static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
    return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D));
  }
  static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) {
    return static_cast<OMPDeclareReductionDecl *>(
        const_cast<DeclContext *>(DC));
  }
};

/// This represents '#pragma omp declare mapper ...' directive. Map clauses are
/// allowed to use with this directive. The following example declares a user
/// defined mapper for the type 'struct vec'. This example instructs the fields
/// 'len' and 'data' should be mapped when mapping instances of 'struct vec'.
///
/// \code
/// #pragma omp declare mapper(mid: struct vec v) map(v.len, v.data[0:N])
/// \endcode
class OMPDeclareMapperDecl final : public OMPDeclarativeDirective<ValueDecl>,
                                   public DeclContext {
  friend class OMPDeclarativeDirective<ValueDecl>;
  friend class ASTDeclReader;
  friend class ASTDeclWriter;

  /// Mapper variable, which is 'v' in the example above
  Expr *MapperVarRef = nullptr;

  /// Name of the mapper variable
  DeclarationName VarName;

  LazyDeclPtr PrevDeclInScope;

  void anchor() override;

  OMPDeclareMapperDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
                       QualType Ty, DeclarationName VarName,
                       OMPDeclareMapperDecl *PrevDeclInScope)
      : OMPDeclarativeDirective<ValueDecl>(OMPDeclareMapper, DC, L, Name, Ty),
        DeclContext(OMPDeclareMapper), VarName(VarName),
        PrevDeclInScope(PrevDeclInScope) {}

  void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) {
    PrevDeclInScope = Prev;
  }

public:
  /// Creates declare mapper node.
  static OMPDeclareMapperDecl *Create(ASTContext &C, DeclContext *DC,
                                      SourceLocation L, DeclarationName Name,
                                      QualType T, DeclarationName VarName,
                                      ArrayRef<OMPClause *> Clauses,
                                      OMPDeclareMapperDecl *PrevDeclInScope);
  /// Creates deserialized declare mapper node.
  static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID,
                                                  unsigned N);

  using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
  using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
  using clauselist_range = llvm::iterator_range<clauselist_iterator>;
  using clauselist_const_range =
      llvm::iterator_range<clauselist_const_iterator>;

  unsigned clauselist_size() const { return Data->getNumClauses(); }
  bool clauselist_empty() const { return Data->getClauses().empty(); }

  clauselist_range clauselists() {
    return clauselist_range(clauselist_begin(), clauselist_end());
  }
  clauselist_const_range clauselists() const {
    return clauselist_const_range(clauselist_begin(), clauselist_end());
  }
  clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
  clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
  clauselist_const_iterator clauselist_begin() const {
    return Data->getClauses().begin();
  }
  clauselist_const_iterator clauselist_end() const {
    return Data->getClauses().end();
  }

  /// Get the variable declared in the mapper
  Expr *getMapperVarRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
  const Expr *getMapperVarRef() const {
    return cast_or_null<Expr>(Data->getChildren()[0]);
  }
  /// Set the variable declared in the mapper
  void setMapperVarRef(Expr *MapperVarRefE) {
    Data->getChildren()[0] = MapperVarRefE;
  }

  /// Get the name of the variable declared in the mapper
  DeclarationName getVarName() { return VarName; }

  /// Get reference to previous declare mapper construct in the same
  /// scope with the same name.
  OMPDeclareMapperDecl *getPrevDeclInScope();
  const OMPDeclareMapperDecl *getPrevDeclInScope() const;

  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  static bool classofKind(Kind K) { return K == OMPDeclareMapper; }
  static DeclContext *castToDeclContext(const OMPDeclareMapperDecl *D) {
    return static_cast<DeclContext *>(const_cast<OMPDeclareMapperDecl *>(D));
  }
  static OMPDeclareMapperDecl *castFromDeclContext(const DeclContext *DC) {
    return static_cast<OMPDeclareMapperDecl *>(const_cast<DeclContext *>(DC));
  }
};

/// Pseudo declaration for capturing expressions. Also is used for capturing of
/// non-static data members in non-static member functions.
///
/// Clang supports capturing of variables only, but OpenMP 4.5 allows to
/// privatize non-static members of current class in non-static member
/// functions. This pseudo-declaration allows properly handle this kind of
/// capture by wrapping captured expression into a variable-like declaration.
class OMPCapturedExprDecl final : public VarDecl {
  friend class ASTDeclReader;
  void anchor() override;

  OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
                      QualType Type, TypeSourceInfo *TInfo,
                      SourceLocation StartLoc)
      : VarDecl(OMPCapturedExpr, C, DC, StartLoc, StartLoc, Id, Type, TInfo,
                SC_None) {
    setImplicit();
  }

public:
  static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
                                     IdentifierInfo *Id, QualType T,
                                     SourceLocation StartLoc);

  static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);

  SourceRange getSourceRange() const override LLVM_READONLY;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
};

/// This represents '#pragma omp requires...' directive.
/// For example
///
/// \code
/// #pragma omp requires unified_address
/// \endcode
///
class OMPRequiresDecl final : public OMPDeclarativeDirective<Decl> {
  friend class OMPDeclarativeDirective<Decl>;
  friend class ASTDeclReader;

  virtual void anchor();

  OMPRequiresDecl(DeclContext *DC, SourceLocation L)
      : OMPDeclarativeDirective<Decl>(OMPRequires, DC, L) {}

public:
  /// Create requires node.
  static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
                                 SourceLocation L, ArrayRef<OMPClause *> CL);
  /// Create deserialized requires node.
  static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID,
                                             unsigned N);

  using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
  using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
  using clauselist_range = llvm::iterator_range<clauselist_iterator>;
  using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;

  unsigned clauselist_size() const { return Data->getNumClauses(); }
  bool clauselist_empty() const { return Data->getClauses().empty(); }

  clauselist_range clauselists() {
    return clauselist_range(clauselist_begin(), clauselist_end());
  }
  clauselist_const_range clauselists() const {
    return clauselist_const_range(clauselist_begin(), clauselist_end());
  }
  clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
  clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
  clauselist_const_iterator clauselist_begin() const {
    return Data->getClauses().begin();
  }
  clauselist_const_iterator clauselist_end() const {
    return Data->getClauses().end();
  }

  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  static bool classofKind(Kind K) { return K == OMPRequires; }
};

/// This represents '#pragma omp allocate ...' directive.
/// For example, in the following, the default allocator is used for both 'a'
/// and 'A::b':
///
/// \code
/// int a;
/// #pragma omp allocate(a)
/// struct A {
///   static int b;
/// #pragma omp allocate(b)
/// };
/// \endcode
///
class OMPAllocateDecl final : public OMPDeclarativeDirective<Decl> {
  friend class OMPDeclarativeDirective<Decl>;
  friend class ASTDeclReader;

  virtual void anchor();

  OMPAllocateDecl(DeclContext *DC, SourceLocation L)
      : OMPDeclarativeDirective<Decl>(OMPAllocate, DC, L) {}

  ArrayRef<const Expr *> getVars() const {
    auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
    return llvm::makeArrayRef(Storage, Data->getNumChildren());
  }

  MutableArrayRef<Expr *> getVars() {
    auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
    return llvm::makeMutableArrayRef(Storage, Data->getNumChildren());
  }

  void setVars(ArrayRef<Expr *> VL);

public:
  static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
                                 SourceLocation L, ArrayRef<Expr *> VL,
                                 ArrayRef<OMPClause *> CL);
  static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID,
                                             unsigned NVars, unsigned NClauses);

  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
  typedef llvm::iterator_range<varlist_iterator> varlist_range;
  typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
  using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
  using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
  using clauselist_range = llvm::iterator_range<clauselist_iterator>;
  using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;

  unsigned varlist_size() const { return Data->getNumChildren(); }
  bool varlist_empty() const { return Data->getChildren().empty(); }
  unsigned clauselist_size() const { return Data->getNumClauses(); }
  bool clauselist_empty() const { return Data->getClauses().empty(); }

  varlist_range varlists() {
    return varlist_range(varlist_begin(), varlist_end());
  }
  varlist_const_range varlists() const {
    return varlist_const_range(varlist_begin(), varlist_end());
  }
  varlist_iterator varlist_begin() { return getVars().begin(); }
  varlist_iterator varlist_end() { return getVars().end(); }
  varlist_const_iterator varlist_begin() const { return getVars().begin(); }
  varlist_const_iterator varlist_end() const { return getVars().end(); }

  clauselist_range clauselists() {
    return clauselist_range(clauselist_begin(), clauselist_end());
  }
  clauselist_const_range clauselists() const {
    return clauselist_const_range(clauselist_begin(), clauselist_end());
  }
  clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
  clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
  clauselist_const_iterator clauselist_begin() const {
    return Data->getClauses().begin();
  }
  clauselist_const_iterator clauselist_end() const {
    return Data->getClauses().end();
  }

  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  static bool classofKind(Kind K) { return K == OMPAllocate; }
};

} // end namespace clang

#endif
