16af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===//
2c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev//
3c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev//                     The LLVM Compiler Infrastructure
4c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev//
5c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev// This file is distributed under the University of Illinois Open Source
6c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev// License. See LICENSE.TXT for details.
7c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev//
8c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev//===----------------------------------------------------------------------===//
9c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev///
10c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// \file
116af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev/// \brief This file defines OpenMP nodes for declarative directives.
12c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev///
13c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev//===----------------------------------------------------------------------===//
14c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
15176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_AST_DECLOPENMP_H
16176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_AST_DECLOPENMP_H
17c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/Decl.h"
194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/Expr.h"
204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/ExternalASTSource.h"
214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/Type.h"
22c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev#include "llvm/ADT/ArrayRef.h"
234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/Support/TrailingObjects.h"
24c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
25c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataevnamespace clang {
26c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
27c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// \brief This represents '#pragma omp threadprivate ...' directive.
28c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// For example, in the following, both 'a' and 'A::b' are threadprivate:
29c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev///
30c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// \code
31c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// int a;
32c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// #pragma omp threadprivate(a)
33c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// struct A {
34c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev///   static int b;
35c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// #pragma omp threadprivate(b)
36c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// };
37c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev/// \endcode
38c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev///
394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass OMPThreadPrivateDecl final
404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    : public Decl,
414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      private llvm::TrailingObjects<OMPThreadPrivateDecl, Expr *> {
42c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  friend class ASTDeclReader;
434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  friend TrailingObjects;
444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
45c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  unsigned NumVars;
46c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
47c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  virtual void anchor();
48c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
49c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
50c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev    Decl(DK, DC, L), NumVars(0) { }
51c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
526af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev  ArrayRef<const Expr *> getVars() const {
534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
54c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  }
55c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
56c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  MutableArrayRef<Expr *> getVars() {
574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
58c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  }
59c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
606af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev  void setVars(ArrayRef<Expr *> VL);
61c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
62c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataevpublic:
63c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
64c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev                                      SourceLocation L,
656af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev                                      ArrayRef<Expr *> VL);
66c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
67c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev                                                  unsigned ID, unsigned N);
68c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
69c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
706af701f29be43e49a25ab098c79940ae4cbb69c7Alexey Bataev  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<varlist_iterator> varlist_range;
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
73c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
74c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  unsigned varlist_size() const { return NumVars; }
75c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  bool varlist_empty() const { return NumVars == 0; }
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  varlist_range varlists() {
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return varlist_range(varlist_begin(), varlist_end());
79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  varlist_const_range varlists() const {
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return varlist_const_range(varlist_begin(), varlist_end());
82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
83c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  varlist_iterator varlist_begin() { return getVars().begin(); }
84c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  varlist_iterator varlist_end() { return getVars().end(); }
85c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  varlist_const_iterator varlist_begin() const { return getVars().begin(); }
86c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  varlist_const_iterator varlist_end() const { return getVars().end(); }
87c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
88c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
89c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev  static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
90c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev};
91c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \brief This represents '#pragma omp declare reduction ...' directive.
934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// For example, in the following, declared reduction 'foo' for types 'int' and
944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// 'float':
954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///
964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \code
974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \
984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///                     initializer (omp_priv = 0)
994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// \endcode
1004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///
1014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
1024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
1034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarprivate:
1044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  friend class ASTDeclReader;
1054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Combiner for declare reduction construct.
1064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Expr *Combiner;
1074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Initializer for declare reduction construct.
1084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Expr *Initializer;
1094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Reference to the previous declare reduction construct in the same
1104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// scope with the same name. Required for proper templates instantiation if
1114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// the declare reduction construct is declared inside compound statement.
1124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  LazyDeclPtr PrevDeclInScope;
1134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  virtual void anchor();
1154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
1174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          DeclarationName Name, QualType Ty,
1184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          OMPDeclareReductionDecl *PrevDeclInScope)
1194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
1204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {}
1214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
1234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PrevDeclInScope = Prev;
1244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
1254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
1274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Create declare reduction node.
1284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static OMPDeclareReductionDecl *
1294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
1304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar         QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
1314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Create deserialized declare reduction node.
1324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
1334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                     unsigned ID);
1344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Get combiner expression of the declare reduction construct.
1364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Expr *getCombiner() { return Combiner; }
1374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const Expr *getCombiner() const { return Combiner; }
1384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Set combiner expression for the declare reduction construct.
1394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void setCombiner(Expr *E) { Combiner = E; }
1404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Get initializer expression (if specified) of the declare reduction
1424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// construct.
1434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Expr *getInitializer() { return Initializer; }
1444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const Expr *getInitializer() const { return Initializer; }
1454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Set initializer expression for the declare reduction construct.
1464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void setInitializer(Expr *E) { Initializer = E; }
1474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \brief Get reference to previous declare reduction construct in the same
1494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// scope with the same name.
1504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPDeclareReductionDecl *getPrevDeclInScope();
1514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const OMPDeclareReductionDecl *getPrevDeclInScope() const;
1524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
1554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
1564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D));
1574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
1584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) {
1594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return static_cast<OMPDeclareReductionDecl *>(
1604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        const_cast<DeclContext *>(DC));
1614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
1624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
1634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Pseudo declaration for capturing expressions. Also is used for capturing of
1654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// non-static data members in non-static member functions.
1664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar///
1674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Clang supports capturing of variables only, but OpenMP 4.5 allows to
1684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// privatize non-static members of current class in non-static member
1694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// functions. This pseudo-declaration allows properly handle this kind of
1704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// capture by wrapping captured expression into a variable-like declaration.
1714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass OMPCapturedExprDecl final : public VarDecl {
1724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  friend class ASTDeclReader;
1734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void anchor() override;
1744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
1764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      QualType Type)
1774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      : VarDecl(OMPCapturedExpr, C, DC, SourceLocation(), SourceLocation(), Id,
1784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                Type, nullptr, SC_None) {
1794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    setImplicit();
1804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
1814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
1834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
1844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                     IdentifierInfo *Id, QualType T);
1854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Implement isa/cast/dyncast/etc.
1894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
1914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
1924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // end namespace clang
194c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
195c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev#endif
196