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