xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- ExprOpenMP.h - Classes for representing expressions ----*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file defines the Expr interface and subclasses.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_EXPROPENMP_H
140b57cec5SDimitry Andric #define LLVM_CLANG_AST_EXPROPENMP_H
150b57cec5SDimitry Andric 
165ffd83dbSDimitry Andric #include "clang/AST/ComputeDependence.h"
170b57cec5SDimitry Andric #include "clang/AST/Expr.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric namespace clang {
205ffd83dbSDimitry Andric /// An explicit cast in C or a C-style cast in C++, which uses the syntax
215ffd83dbSDimitry Andric /// ([s1][s2]...[sn])expr. For example: @c ([3][3])f.
225ffd83dbSDimitry Andric class OMPArrayShapingExpr final
235ffd83dbSDimitry Andric     : public Expr,
245ffd83dbSDimitry Andric       private llvm::TrailingObjects<OMPArrayShapingExpr, Expr *, SourceRange> {
255ffd83dbSDimitry Andric   friend TrailingObjects;
265ffd83dbSDimitry Andric   friend class ASTStmtReader;
275ffd83dbSDimitry Andric   friend class ASTStmtWriter;
285ffd83dbSDimitry Andric   /// Base node.
295ffd83dbSDimitry Andric   SourceLocation LPLoc; /// The location of the left paren
305ffd83dbSDimitry Andric   SourceLocation RPLoc; /// The location of the right paren
315ffd83dbSDimitry Andric   unsigned NumDims = 0; /// Number of dimensions in the shaping expression.
325ffd83dbSDimitry Andric 
335ffd83dbSDimitry Andric   /// Construct full expression.
345ffd83dbSDimitry Andric   OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L,
355ffd83dbSDimitry Andric                       SourceLocation R, ArrayRef<Expr *> Dims);
365ffd83dbSDimitry Andric 
375ffd83dbSDimitry Andric   /// Construct an empty expression.
OMPArrayShapingExpr(EmptyShell Shell,unsigned NumDims)385ffd83dbSDimitry Andric   explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims)
395ffd83dbSDimitry Andric       : Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {}
405ffd83dbSDimitry Andric 
415ffd83dbSDimitry Andric   /// Sets the dimensions for the array shaping.
425ffd83dbSDimitry Andric   void setDimensions(ArrayRef<Expr *> Dims);
435ffd83dbSDimitry Andric 
445ffd83dbSDimitry Andric   /// Sets the base expression for array shaping operation.
setBase(Expr * Op)455ffd83dbSDimitry Andric   void setBase(Expr *Op) { getTrailingObjects<Expr *>()[NumDims] = Op; }
465ffd83dbSDimitry Andric 
475ffd83dbSDimitry Andric   /// Sets source ranges for the brackets in the array shaping operation.
485ffd83dbSDimitry Andric   void setBracketsRanges(ArrayRef<SourceRange> BR);
495ffd83dbSDimitry Andric 
numTrailingObjects(OverloadToken<Expr * >)505ffd83dbSDimitry Andric   unsigned numTrailingObjects(OverloadToken<Expr *>) const {
515ffd83dbSDimitry Andric     // Add an extra one for the base expression.
525ffd83dbSDimitry Andric     return NumDims + 1;
535ffd83dbSDimitry Andric   }
545ffd83dbSDimitry Andric 
numTrailingObjects(OverloadToken<SourceRange>)555ffd83dbSDimitry Andric   unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
565ffd83dbSDimitry Andric     return NumDims;
575ffd83dbSDimitry Andric   }
585ffd83dbSDimitry Andric 
595ffd83dbSDimitry Andric public:
605ffd83dbSDimitry Andric   static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T,
615ffd83dbSDimitry Andric                                      Expr *Op, SourceLocation L,
625ffd83dbSDimitry Andric                                      SourceLocation R, ArrayRef<Expr *> Dims,
635ffd83dbSDimitry Andric                                      ArrayRef<SourceRange> BracketRanges);
645ffd83dbSDimitry Andric 
655ffd83dbSDimitry Andric   static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context,
665ffd83dbSDimitry Andric                                           unsigned NumDims);
675ffd83dbSDimitry Andric 
getLParenLoc()685ffd83dbSDimitry Andric   SourceLocation getLParenLoc() const { return LPLoc; }
setLParenLoc(SourceLocation L)695ffd83dbSDimitry Andric   void setLParenLoc(SourceLocation L) { LPLoc = L; }
705ffd83dbSDimitry Andric 
getRParenLoc()715ffd83dbSDimitry Andric   SourceLocation getRParenLoc() const { return RPLoc; }
setRParenLoc(SourceLocation L)725ffd83dbSDimitry Andric   void setRParenLoc(SourceLocation L) { RPLoc = L; }
735ffd83dbSDimitry Andric 
getBeginLoc()745ffd83dbSDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
getEndLoc()755ffd83dbSDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
765ffd83dbSDimitry Andric     return getBase()->getEndLoc();
775ffd83dbSDimitry Andric   }
785ffd83dbSDimitry Andric 
795ffd83dbSDimitry Andric   /// Fetches the dimensions for array shaping expression.
getDimensions()805ffd83dbSDimitry Andric   ArrayRef<Expr *> getDimensions() const {
81*bdd1243dSDimitry Andric     return llvm::ArrayRef(getTrailingObjects<Expr *>(), NumDims);
825ffd83dbSDimitry Andric   }
835ffd83dbSDimitry Andric 
845ffd83dbSDimitry Andric   /// Fetches source ranges for the brackets os the array shaping expression.
getBracketsRanges()855ffd83dbSDimitry Andric   ArrayRef<SourceRange> getBracketsRanges() const {
86*bdd1243dSDimitry Andric     return llvm::ArrayRef(getTrailingObjects<SourceRange>(), NumDims);
875ffd83dbSDimitry Andric   }
885ffd83dbSDimitry Andric 
895ffd83dbSDimitry Andric   /// Fetches base expression of array shaping expression.
getBase()905ffd83dbSDimitry Andric   Expr *getBase() { return getTrailingObjects<Expr *>()[NumDims]; }
getBase()915ffd83dbSDimitry Andric   const Expr *getBase() const { return getTrailingObjects<Expr *>()[NumDims]; }
925ffd83dbSDimitry Andric 
classof(const Stmt * T)935ffd83dbSDimitry Andric   static bool classof(const Stmt *T) {
945ffd83dbSDimitry Andric     return T->getStmtClass() == OMPArrayShapingExprClass;
955ffd83dbSDimitry Andric   }
965ffd83dbSDimitry Andric 
975ffd83dbSDimitry Andric   // Iterators
children()985ffd83dbSDimitry Andric   child_range children() {
995ffd83dbSDimitry Andric     Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
1005ffd83dbSDimitry Andric     return child_range(Begin, Begin + NumDims + 1);
1015ffd83dbSDimitry Andric   }
children()1025ffd83dbSDimitry Andric   const_child_range children() const {
1035ffd83dbSDimitry Andric     Stmt *const *Begin =
1045ffd83dbSDimitry Andric         reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
1055ffd83dbSDimitry Andric     return const_child_range(Begin, Begin + NumDims + 1);
1065ffd83dbSDimitry Andric   }
1075ffd83dbSDimitry Andric };
1085ffd83dbSDimitry Andric 
1095ffd83dbSDimitry Andric /// Helper expressions and declaration for OMPIteratorExpr class for each
1105ffd83dbSDimitry Andric /// iteration space.
1115ffd83dbSDimitry Andric struct OMPIteratorHelperData {
1125ffd83dbSDimitry Andric   /// Internal normalized counter.
1135ffd83dbSDimitry Andric   VarDecl *CounterVD = nullptr;
1145ffd83dbSDimitry Andric   /// Normalized upper bound. Normalized loop iterates from 0 to Upper with
1155ffd83dbSDimitry Andric   /// step 1.
1165ffd83dbSDimitry Andric   Expr *Upper = nullptr;
1175ffd83dbSDimitry Andric   /// Update expression for the originally specified iteration variable,
1185ffd83dbSDimitry Andric   /// calculated as VD = Begin + CounterVD * Step;
1195ffd83dbSDimitry Andric   Expr *Update = nullptr;
1205ffd83dbSDimitry Andric   /// Updater for the internal counter: ++CounterVD;
1215ffd83dbSDimitry Andric   Expr *CounterUpdate = nullptr;
1225ffd83dbSDimitry Andric };
1235ffd83dbSDimitry Andric 
1245ffd83dbSDimitry Andric /// OpenMP 5.0 [2.1.6 Iterators]
1255ffd83dbSDimitry Andric /// Iterators are identifiers that expand to multiple values in the clause on
1265ffd83dbSDimitry Andric /// which they appear.
1275ffd83dbSDimitry Andric /// The syntax of the iterator modifier is as follows:
1285ffd83dbSDimitry Andric /// \code
1295ffd83dbSDimitry Andric /// iterator(iterators-definition)
1305ffd83dbSDimitry Andric /// \endcode
1315ffd83dbSDimitry Andric /// where iterators-definition is one of the following:
1325ffd83dbSDimitry Andric /// \code
1335ffd83dbSDimitry Andric /// iterator-specifier [, iterators-definition ]
1345ffd83dbSDimitry Andric /// \endcode
1355ffd83dbSDimitry Andric /// where iterator-specifier is one of the following:
1365ffd83dbSDimitry Andric /// \code
1375ffd83dbSDimitry Andric /// [ iterator-type ] identifier = range-specification
1385ffd83dbSDimitry Andric /// \endcode
1395ffd83dbSDimitry Andric /// where identifier is a base language identifier.
1405ffd83dbSDimitry Andric /// iterator-type is a type name.
1415ffd83dbSDimitry Andric /// range-specification is of the form begin:end[:step], where begin and end are
1425ffd83dbSDimitry Andric /// expressions for which their types can be converted to iterator-type and step
1435ffd83dbSDimitry Andric /// is an integral expression.
1445ffd83dbSDimitry Andric /// In an iterator-specifier, if the iterator-type is not specified then the
1455ffd83dbSDimitry Andric /// type of that iterator is of int type.
1465ffd83dbSDimitry Andric /// The iterator-type must be an integral or pointer type.
1475ffd83dbSDimitry Andric /// The iterator-type must not be const qualified.
1485ffd83dbSDimitry Andric class OMPIteratorExpr final
1495ffd83dbSDimitry Andric     : public Expr,
1505ffd83dbSDimitry Andric       private llvm::TrailingObjects<OMPIteratorExpr, Decl *, Expr *,
1515ffd83dbSDimitry Andric                                     SourceLocation, OMPIteratorHelperData> {
1525ffd83dbSDimitry Andric public:
1535ffd83dbSDimitry Andric   /// Iterator range representation begin:end[:step].
1545ffd83dbSDimitry Andric   struct IteratorRange {
1555ffd83dbSDimitry Andric     Expr *Begin = nullptr;
1565ffd83dbSDimitry Andric     Expr *End = nullptr;
1575ffd83dbSDimitry Andric     Expr *Step = nullptr;
1585ffd83dbSDimitry Andric   };
1595ffd83dbSDimitry Andric   /// Iterator definition representation.
1605ffd83dbSDimitry Andric   struct IteratorDefinition {
1615ffd83dbSDimitry Andric     Decl *IteratorDecl = nullptr;
1625ffd83dbSDimitry Andric     IteratorRange Range;
1635ffd83dbSDimitry Andric     SourceLocation AssignmentLoc;
1645ffd83dbSDimitry Andric     SourceLocation ColonLoc, SecondColonLoc;
1655ffd83dbSDimitry Andric   };
1665ffd83dbSDimitry Andric 
1675ffd83dbSDimitry Andric private:
1685ffd83dbSDimitry Andric   friend TrailingObjects;
1695ffd83dbSDimitry Andric   friend class ASTStmtReader;
1705ffd83dbSDimitry Andric   friend class ASTStmtWriter;
1715ffd83dbSDimitry Andric 
1725ffd83dbSDimitry Andric   /// Offset in the list of expressions for subelements of the ranges.
1735ffd83dbSDimitry Andric   enum class RangeExprOffset {
1745ffd83dbSDimitry Andric     Begin = 0,
1755ffd83dbSDimitry Andric     End = 1,
1765ffd83dbSDimitry Andric     Step = 2,
1775ffd83dbSDimitry Andric     Total = 3,
1785ffd83dbSDimitry Andric   };
1795ffd83dbSDimitry Andric   /// Offset in the list of locations for subelements of colon symbols
1805ffd83dbSDimitry Andric   /// locations.
1815ffd83dbSDimitry Andric   enum class RangeLocOffset {
1825ffd83dbSDimitry Andric     AssignLoc = 0,
1835ffd83dbSDimitry Andric     FirstColonLoc = 1,
1845ffd83dbSDimitry Andric     SecondColonLoc = 2,
1855ffd83dbSDimitry Andric     Total = 3,
1865ffd83dbSDimitry Andric   };
1875ffd83dbSDimitry Andric   /// Location of 'iterator' keyword.
1885ffd83dbSDimitry Andric   SourceLocation IteratorKwLoc;
1895ffd83dbSDimitry Andric   /// Location of '('.
1905ffd83dbSDimitry Andric   SourceLocation LPLoc;
1915ffd83dbSDimitry Andric   /// Location of ')'.
1925ffd83dbSDimitry Andric   SourceLocation RPLoc;
1935ffd83dbSDimitry Andric   /// Number of iterator definitions.
1945ffd83dbSDimitry Andric   unsigned NumIterators = 0;
1955ffd83dbSDimitry Andric 
1965ffd83dbSDimitry Andric   OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc,
1975ffd83dbSDimitry Andric                   SourceLocation L, SourceLocation R,
1985ffd83dbSDimitry Andric                   ArrayRef<IteratorDefinition> Data,
1995ffd83dbSDimitry Andric                   ArrayRef<OMPIteratorHelperData> Helpers);
2005ffd83dbSDimitry Andric 
2015ffd83dbSDimitry Andric   /// Construct an empty expression.
OMPIteratorExpr(EmptyShell Shell,unsigned NumIterators)2025ffd83dbSDimitry Andric   explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators)
2035ffd83dbSDimitry Andric       : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {}
2045ffd83dbSDimitry Andric 
2055ffd83dbSDimitry Andric   /// Sets basic declaration for the specified iterator definition.
2065ffd83dbSDimitry Andric   void setIteratorDeclaration(unsigned I, Decl *D);
2075ffd83dbSDimitry Andric 
2085ffd83dbSDimitry Andric   /// Sets the location of the assignment symbol for the specified iterator
2095ffd83dbSDimitry Andric   /// definition.
2105ffd83dbSDimitry Andric   void setAssignmentLoc(unsigned I, SourceLocation Loc);
2115ffd83dbSDimitry Andric 
2125ffd83dbSDimitry Andric   /// Sets begin, end and optional step expressions for specified iterator
2135ffd83dbSDimitry Andric   /// definition.
2145ffd83dbSDimitry Andric   void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc,
2155ffd83dbSDimitry Andric                         Expr *End, SourceLocation SecondColonLoc, Expr *Step);
2165ffd83dbSDimitry Andric 
2175ffd83dbSDimitry Andric   /// Sets helpers for the specified iteration space.
2185ffd83dbSDimitry Andric   void setHelper(unsigned I, const OMPIteratorHelperData &D);
2195ffd83dbSDimitry Andric 
numTrailingObjects(OverloadToken<Decl * >)2205ffd83dbSDimitry Andric   unsigned numTrailingObjects(OverloadToken<Decl *>) const {
2215ffd83dbSDimitry Andric     return NumIterators;
2225ffd83dbSDimitry Andric   }
2235ffd83dbSDimitry Andric 
numTrailingObjects(OverloadToken<Expr * >)2245ffd83dbSDimitry Andric   unsigned numTrailingObjects(OverloadToken<Expr *>) const {
2255ffd83dbSDimitry Andric     return NumIterators * static_cast<int>(RangeExprOffset::Total);
2265ffd83dbSDimitry Andric   }
2275ffd83dbSDimitry Andric 
numTrailingObjects(OverloadToken<SourceLocation>)2285ffd83dbSDimitry Andric   unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
2295ffd83dbSDimitry Andric     return NumIterators * static_cast<int>(RangeLocOffset::Total);
2305ffd83dbSDimitry Andric   }
2315ffd83dbSDimitry Andric 
2325ffd83dbSDimitry Andric public:
2335ffd83dbSDimitry Andric   static OMPIteratorExpr *Create(const ASTContext &Context, QualType T,
2345ffd83dbSDimitry Andric                                  SourceLocation IteratorKwLoc, SourceLocation L,
2355ffd83dbSDimitry Andric                                  SourceLocation R,
2365ffd83dbSDimitry Andric                                  ArrayRef<IteratorDefinition> Data,
2375ffd83dbSDimitry Andric                                  ArrayRef<OMPIteratorHelperData> Helpers);
2385ffd83dbSDimitry Andric 
2395ffd83dbSDimitry Andric   static OMPIteratorExpr *CreateEmpty(const ASTContext &Context,
2405ffd83dbSDimitry Andric                                       unsigned NumIterators);
2415ffd83dbSDimitry Andric 
getLParenLoc()2425ffd83dbSDimitry Andric   SourceLocation getLParenLoc() const { return LPLoc; }
setLParenLoc(SourceLocation L)2435ffd83dbSDimitry Andric   void setLParenLoc(SourceLocation L) { LPLoc = L; }
2445ffd83dbSDimitry Andric 
getRParenLoc()2455ffd83dbSDimitry Andric   SourceLocation getRParenLoc() const { return RPLoc; }
setRParenLoc(SourceLocation L)2465ffd83dbSDimitry Andric   void setRParenLoc(SourceLocation L) { RPLoc = L; }
2475ffd83dbSDimitry Andric 
getIteratorKwLoc()2485ffd83dbSDimitry Andric   SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; }
setIteratorKwLoc(SourceLocation L)2495ffd83dbSDimitry Andric   void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; }
getBeginLoc()2505ffd83dbSDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; }
getEndLoc()2515ffd83dbSDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; }
2525ffd83dbSDimitry Andric 
2535ffd83dbSDimitry Andric   /// Gets the iterator declaration for the given iterator.
2545ffd83dbSDimitry Andric   Decl *getIteratorDecl(unsigned I);
getIteratorDecl(unsigned I)2555ffd83dbSDimitry Andric   const Decl *getIteratorDecl(unsigned I) const {
2565ffd83dbSDimitry Andric     return const_cast<OMPIteratorExpr *>(this)->getIteratorDecl(I);
2575ffd83dbSDimitry Andric   }
2585ffd83dbSDimitry Andric 
2595ffd83dbSDimitry Andric   /// Gets the iterator range for the given iterator.
2605ffd83dbSDimitry Andric   IteratorRange getIteratorRange(unsigned I);
getIteratorRange(unsigned I)2615ffd83dbSDimitry Andric   const IteratorRange getIteratorRange(unsigned I) const {
2625ffd83dbSDimitry Andric     return const_cast<OMPIteratorExpr *>(this)->getIteratorRange(I);
2635ffd83dbSDimitry Andric   }
2645ffd83dbSDimitry Andric 
2655ffd83dbSDimitry Andric   /// Gets the location of '=' for the given iterator definition.
2665ffd83dbSDimitry Andric   SourceLocation getAssignLoc(unsigned I) const;
2675ffd83dbSDimitry Andric   /// Gets the location of the first ':' in the range for the given iterator
2685ffd83dbSDimitry Andric   /// definition.
2695ffd83dbSDimitry Andric   SourceLocation getColonLoc(unsigned I) const;
2705ffd83dbSDimitry Andric   /// Gets the location of the second ':' (if any) in the range for the given
2715ffd83dbSDimitry Andric   /// iteratori definition.
2725ffd83dbSDimitry Andric   SourceLocation getSecondColonLoc(unsigned I) const;
2735ffd83dbSDimitry Andric 
2745ffd83dbSDimitry Andric   /// Returns number of iterator definitions.
numOfIterators()2755ffd83dbSDimitry Andric   unsigned numOfIterators() const { return NumIterators; }
2765ffd83dbSDimitry Andric 
2775ffd83dbSDimitry Andric   /// Fetches helper data for the specified iteration space.
2785ffd83dbSDimitry Andric   OMPIteratorHelperData &getHelper(unsigned I);
2795ffd83dbSDimitry Andric   const OMPIteratorHelperData &getHelper(unsigned I) const;
2805ffd83dbSDimitry Andric 
classof(const Stmt * T)2815ffd83dbSDimitry Andric   static bool classof(const Stmt *T) {
2825ffd83dbSDimitry Andric     return T->getStmtClass() == OMPIteratorExprClass;
2835ffd83dbSDimitry Andric   }
2845ffd83dbSDimitry Andric 
2855ffd83dbSDimitry Andric   // Iterators
children()2865ffd83dbSDimitry Andric   child_range children() {
2875ffd83dbSDimitry Andric     Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
2885ffd83dbSDimitry Andric     return child_range(
2895ffd83dbSDimitry Andric         Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
2905ffd83dbSDimitry Andric   }
children()2915ffd83dbSDimitry Andric   const_child_range children() const {
2925ffd83dbSDimitry Andric     Stmt *const *Begin =
2935ffd83dbSDimitry Andric         reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
2945ffd83dbSDimitry Andric     return const_child_range(
2955ffd83dbSDimitry Andric         Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
2965ffd83dbSDimitry Andric   }
2975ffd83dbSDimitry Andric };
2985ffd83dbSDimitry Andric 
2990b57cec5SDimitry Andric } // end namespace clang
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric #endif
302