diff options
| author | Samuel Antao <sfantao@us.ibm.com> | 2016-04-26 14:54:23 +0000 |
|---|---|---|
| committer | Samuel Antao <sfantao@us.ibm.com> | 2016-04-26 14:54:23 +0000 |
| commit | 90927006833f81e544f9c84d712d574c492e7d38 (patch) | |
| tree | 091867910c327dae6d70762fe6f4b132ebcc362c /clang/include | |
| parent | 792374b94181c313dd722ee200fa265b9a464bbe (diff) | |
| download | bcm5719-llvm-90927006833f81e544f9c84d712d574c492e7d38.tar.gz bcm5719-llvm-90927006833f81e544f9c84d712d574c492e7d38.zip | |
[OpenMP] Improve mappable expressions Sema.
Summary:
This patch adds logic to save the components of mappable expressions in the clause that uses it, so that they don't have to be recomputed during codegen. Given that the mappable components are (will be) used in several clauses a new geneneric implementation `OMPMappableExprListClause` is used that extends the existing `OMPVarListClause`.
This patch does not add new tests. The goal is to preserve the existing functionality while storing more info in the clauses.
Reviewers: hfinkel, carlo.bertolli, arpith-jacob, kkwli0, ABataev
Subscribers: cfe-commits, caomhin
Differential Revision: http://reviews.llvm.org/D19382
llvm-svn: 267560
Diffstat (limited to 'clang/include')
| -rw-r--r-- | clang/include/clang/AST/OpenMPClause.h | 568 |
1 files changed, 550 insertions, 18 deletions
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 48a03b17141..c11a4d6e1d1 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -2774,6 +2774,495 @@ public: } }; +/// \brief Struct that defines common infrastructure to handle mappable +/// expressions used in OpenMP clauses. +class OMPClauseMappableExprCommon { +public: + // \brief Class that represents a component of a mappable expression. E.g. + // for an expression S.a, the first component is a declaration reference + // expression associated with 'S' and the second is a member expression + // associated with the field declaration 'a'. If the expression is an array + // subscript it may not have any associated declaration. In that case the + // associated declaration is set to nullptr. + class MappableComponent { + // \brief Expression associated with the component. + Expr *AssociatedExpression = nullptr; + // \brief Declaration associated with the declaration. If the component does + // not have a declaration (e.g. array subscripts or section), this is set to + // nullptr. + ValueDecl *AssociatedDeclaration = nullptr; + + public: + explicit MappableComponent() {} + explicit MappableComponent(Expr *AssociatedExpression, + ValueDecl *AssociatedDeclaration) + : AssociatedExpression(AssociatedExpression), + AssociatedDeclaration( + AssociatedDeclaration + ? cast<ValueDecl>(AssociatedDeclaration->getCanonicalDecl()) + : nullptr) {} + + Expr *getAssociatedExpression() const { return AssociatedExpression; } + ValueDecl *getAssociatedDeclaration() const { + return AssociatedDeclaration; + } + }; + + // \brief List of components of an expression. This first one is the whole + // expression and the last one is the base expression. + typedef SmallVector<MappableComponent, 8> MappableExprComponentList; + typedef ArrayRef<MappableComponent> MappableExprComponentListRef; + + // \brief List of all component lists associated to the same base declaration. + // E.g. if both 'S.a' and 'S.b' are a mappable expressions, each will have + // their component list but the same base declaration 'S'. + typedef SmallVector<MappableExprComponentList, 8> MappableExprComponentLists; + typedef ArrayRef<MappableExprComponentList> MappableExprComponentListsRef; + +protected: + // \brief Return the total number of elements in a list of component lists. + static unsigned + getComponentsTotalNumber(MappableExprComponentListsRef ComponentLists); + + // \brief Return the total number of elements in a list of declarations. All + // declarations are expected to be canonical. + static unsigned + getUniqueDeclarationsTotalNumber(ArrayRef<ValueDecl *> Declarations); +}; + +/// \brief This represents clauses with a list of expressions that are mappable. +/// Examples of these clauses are 'map' in +/// '#pragma omp target [enter|exit] [data]...' directives, and 'to' and 'from +/// in '#pragma omp target update...' directives. +template <class T> +class OMPMappableExprListClause : public OMPVarListClause<T>, + public OMPClauseMappableExprCommon { + friend class OMPClauseReader; + + /// \brief Number of unique declarations in this clause. + unsigned NumUniqueDeclarations; + + /// \brief Number of component lists in this clause. + unsigned NumComponentLists; + + /// \brief Total number of components in this clause. + unsigned NumComponents; + +protected: + /// \brief Get the unique declarations that are in the trailing objects of the + /// class. + MutableArrayRef<ValueDecl *> getUniqueDeclsRef() { + return MutableArrayRef<ValueDecl *>( + static_cast<T *>(this)->template getTrailingObjects<ValueDecl *>(), + NumUniqueDeclarations); + } + + /// \brief Get the unique declarations that are in the trailing objects of the + /// class. + ArrayRef<ValueDecl *> getUniqueDeclsRef() const { + return ArrayRef<ValueDecl *>( + static_cast<const T *>(this) + ->template getTrailingObjects<ValueDecl *>(), + NumUniqueDeclarations); + } + + /// \brief Set the unique declarations that are in the trailing objects of the + /// class. + void setUniqueDecls(ArrayRef<ValueDecl *> UDs) { + assert(UDs.size() == NumUniqueDeclarations && + "Unexpected amount of unique declarations."); + std::copy(UDs.begin(), UDs.end(), getUniqueDeclsRef().begin()); + } + + /// \brief Get the number of lists per declaration that are in the trailing + /// objects of the class. + MutableArrayRef<unsigned> getDeclNumListsRef() { + return MutableArrayRef<unsigned>( + static_cast<T *>(this)->template getTrailingObjects<unsigned>(), + NumUniqueDeclarations); + } + + /// \brief Get the number of lists per declaration that are in the trailing + /// objects of the class. + ArrayRef<unsigned> getDeclNumListsRef() const { + return ArrayRef<unsigned>( + static_cast<const T *>(this)->template getTrailingObjects<unsigned>(), + NumUniqueDeclarations); + } + + /// \brief Set the number of lists per declaration that are in the trailing + /// objects of the class. + void setDeclNumLists(ArrayRef<unsigned> DNLs) { + assert(DNLs.size() == NumUniqueDeclarations && + "Unexpected amount of list numbers."); + std::copy(DNLs.begin(), DNLs.end(), getDeclNumListsRef().begin()); + } + + /// \brief Get the cumulative component lists sizes that are in the trailing + /// objects of the class. They are appended after the number of lists. + MutableArrayRef<unsigned> getComponentListSizesRef() { + return MutableArrayRef<unsigned>( + static_cast<T *>(this)->template getTrailingObjects<unsigned>() + + NumUniqueDeclarations, + NumComponentLists); + } + + /// \brief Get the cumulative component lists sizes that are in the trailing + /// objects of the class. They are appended after the number of lists. + ArrayRef<unsigned> getComponentListSizesRef() const { + return ArrayRef<unsigned>( + static_cast<const T *>(this)->template getTrailingObjects<unsigned>() + + NumUniqueDeclarations, + NumComponentLists); + } + + /// \brief Set the cumulative component lists sizes that are in the trailing + /// objects of the class. + void setComponentListSizes(ArrayRef<unsigned> CLSs) { + assert(CLSs.size() == NumComponentLists && + "Unexpected amount of component lists."); + std::copy(CLSs.begin(), CLSs.end(), getComponentListSizesRef().begin()); + } + + /// \brief Get the components that are in the trailing objects of the class. + MutableArrayRef<MappableComponent> getComponentsRef() { + return MutableArrayRef<MappableComponent>( + static_cast<T *>(this) + ->template getTrailingObjects<MappableComponent>(), + NumComponents); + } + + /// \brief Get the components that are in the trailing objects of the class. + ArrayRef<MappableComponent> getComponentsRef() const { + return ArrayRef<MappableComponent>( + static_cast<const T *>(this) + ->template getTrailingObjects<MappableComponent>(), + NumComponents); + } + + /// \brief Set the components that are in the trailing objects of the class. + /// This requires the list sizes so that it can also fill the original + /// expressions, which are the first component of each list. + void setComponents(ArrayRef<MappableComponent> Components, + ArrayRef<unsigned> CLSs) { + assert(Components.size() == NumComponents && + "Unexpected amount of component lists."); + assert(CLSs.size() == NumComponentLists && + "Unexpected amount of list sizes."); + std::copy(Components.begin(), Components.end(), getComponentsRef().begin()); + } + + /// \brief Fill the clause information from the list of declarations and + /// associated component lists. + void setClauseInfo(ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists) { + // Perform some checks to make sure the data sizes are consistent with the + // information available when the clause was created. + assert(getUniqueDeclarationsTotalNumber(Declarations) == + NumUniqueDeclarations && + "Unexpected number of mappable expression info entries!"); + assert(getComponentsTotalNumber(ComponentLists) == NumComponents && + "Unexpected total number of components!"); + assert(Declarations.size() == ComponentLists.size() && + "Declaration and component lists size is not consistent!"); + assert(Declarations.size() == NumComponentLists && + "Unexpected declaration and component lists size!"); + + // Organize the components by declaration and retrieve the original + // expression. Original expressions are always the first component of the + // mappable component list. + llvm::DenseMap<ValueDecl *, SmallVector<MappableExprComponentListRef, 8>> + ComponentListMap; + { + auto CI = ComponentLists.begin(); + for (auto DI = Declarations.begin(), DE = Declarations.end(); DI != DE; + ++DI, ++CI) { + assert(!CI->empty() && "Invalid component list!"); + ComponentListMap[*DI].push_back(*CI); + } + } + + // Iterators of the target storage. + auto UniqueDeclarations = getUniqueDeclsRef(); + auto UDI = UniqueDeclarations.begin(); + + auto DeclNumLists = getDeclNumListsRef(); + auto DNLI = DeclNumLists.begin(); + + auto ComponentListSizes = getComponentListSizesRef(); + auto CLSI = ComponentListSizes.begin(); + + auto Components = getComponentsRef(); + auto CI = Components.begin(); + + // Variable to compute the accumulation of the number of components. + unsigned PrevSize = 0u; + + // Scan all the declarations and associated component lists. + for (auto &M : ComponentListMap) { + // The declaration. + auto *D = M.first; + // The component lists. + auto CL = M.second; + + // Initialize the entry. + *UDI = D; + ++UDI; + + *DNLI = CL.size(); + ++DNLI; + + // Obtain the cumulative sizes and concatenate all the components in the + // reserved storage. + for (auto C : CL) { + // Accumulate with the previous size. + PrevSize += C.size(); + + // Save the size. + *CLSI = PrevSize; + ++CLSI; + + // Append components after the current components iterator. + CI = std::copy(C.begin(), C.end(), CI); + } + } + } + + /// \brief Build a clause for \a NumUniqueDeclarations declarations, \a + /// NumComponentLists total component lists, and \a NumComponents total + /// components. + /// + /// \param K Kind of the clause. + /// \param StartLoc Starting location of the clause (the clause keyword). + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause - one + /// list for each expression in the clause. + /// \param NumComponents Total number of expression components in the clause. + /// + OMPMappableExprListClause(OpenMPClauseKind K, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPVarListClause<T>(K, StartLoc, LParenLoc, EndLoc, NumVars), + NumUniqueDeclarations(NumUniqueDeclarations), + NumComponentLists(NumComponentLists), NumComponents(NumComponents) {} + +public: + /// \brief Return the number of unique base declarations in this clause. + unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; } + /// \brief Return the number of lists derived from the clause expressions. + unsigned getTotalComponentListNum() const { return NumComponentLists; } + /// \brief Return the total number of components in all lists derived from the + /// clause. + unsigned getTotalComponentsNum() const { return NumComponents; } + + /// \brief Iterator that browse the components by lists. It also allows + /// browsing components of a single declaration. + class const_component_lists_iterator + : public llvm::iterator_adaptor_base< + const_component_lists_iterator, + MappableExprComponentListRef::const_iterator, + std::forward_iterator_tag, MappableComponent, ptrdiff_t, + MappableComponent, MappableComponent> { + // The declaration the iterator currently refers to. + ArrayRef<ValueDecl *>::iterator DeclCur; + + // The list number associated with the current declaration. + ArrayRef<unsigned>::iterator NumListsCur; + + // Remaining lists for the current declaration. + unsigned RemainingLists; + + // The cumulative size of the previous list, or zero if there is no previous + // list. + unsigned PrevListSize; + + // The cumulative sizes of the current list - it will delimit the remaining + // range of interest. + ArrayRef<unsigned>::const_iterator ListSizeCur; + ArrayRef<unsigned>::const_iterator ListSizeEnd; + + // Iterator to the end of the components storage. + MappableExprComponentListRef::const_iterator End; + + public: + /// \brief Construct an iterator that scans all lists. + explicit const_component_lists_iterator( + ArrayRef<ValueDecl *> UniqueDecls, ArrayRef<unsigned> DeclsListNum, + ArrayRef<unsigned> CumulativeListSizes, + MappableExprComponentListRef Components) + : const_component_lists_iterator::iterator_adaptor_base( + Components.begin()), + DeclCur(UniqueDecls.begin()), NumListsCur(DeclsListNum.begin()), + RemainingLists(0u), PrevListSize(0u), + ListSizeCur(CumulativeListSizes.begin()), + ListSizeEnd(CumulativeListSizes.end()), End(Components.end()) { + assert(UniqueDecls.size() == DeclsListNum.size() && + "Inconsistent number of declarations and list sizes!"); + if (!DeclsListNum.empty()) + RemainingLists = *NumListsCur; + } + + /// \brief Construct an iterator that scan lists for a given declaration \a + /// Declaration. + explicit const_component_lists_iterator( + const ValueDecl *Declaration, ArrayRef<ValueDecl *> UniqueDecls, + ArrayRef<unsigned> DeclsListNum, ArrayRef<unsigned> CumulativeListSizes, + MappableExprComponentListRef Components) + : const_component_lists_iterator(UniqueDecls, DeclsListNum, + CumulativeListSizes, Components) { + + // Look for the desired declaration. While we are looking for it, we + // update the state so that we know the component where a given list + // starts. + for (; DeclCur != UniqueDecls.end(); ++DeclCur, ++NumListsCur) { + if (*DeclCur == Declaration) + break; + + assert(*NumListsCur > 0 && "No lists associated with declaration??"); + + // Skip the lists associated with the current declaration, but save the + // last list size that was skipped. + std::advance(ListSizeCur, *NumListsCur - 1); + PrevListSize = *ListSizeCur; + ++ListSizeCur; + } + + // If we didn't find any declaration, advance the iterator to after the + // last component and set remaining lists to zero. + if (ListSizeCur == CumulativeListSizes.end()) { + this->I = End; + RemainingLists = 0u; + return; + } + + // Set the remaining lists with the total number of lists of the current + // declaration. + RemainingLists = *NumListsCur; + + // Adjust the list size end iterator to the end of the relevant range. + ListSizeEnd = ListSizeCur; + std::advance(ListSizeEnd, RemainingLists); + + // Given that the list sizes are cumulative, the index of the component + // that start the list is the size of the previous list. + std::advance(this->I, PrevListSize); + } + + // Return the array with the current list. The sizes are cumulative, so the + // array size is the difference between the current size and previous one. + std::pair<const ValueDecl *, MappableExprComponentListRef> + operator*() const { + assert(ListSizeCur != ListSizeEnd && "Invalid iterator!"); + return std::make_pair( + *DeclCur, + MappableExprComponentListRef(&*this->I, *ListSizeCur - PrevListSize)); + } + std::pair<const ValueDecl *, MappableExprComponentListRef> + operator->() const { + return **this; + } + + // Skip the components of the current list. + const_component_lists_iterator &operator++() { + assert(ListSizeCur != ListSizeEnd && RemainingLists && + "Invalid iterator!"); + + // If we don't have more lists just skip all the components. Otherwise, + // advance the iterator by the number of components in the current list. + if (std::next(ListSizeCur) == ListSizeEnd) { + this->I = End; + RemainingLists = 0; + } else { + std::advance(this->I, *ListSizeCur - PrevListSize); + PrevListSize = *ListSizeCur; + + // We are done with a declaration, move to the next one. + if (!(--RemainingLists)) { + ++DeclCur; + ++NumListsCur; + RemainingLists = *NumListsCur; + assert(RemainingLists && "No lists in the following declaration??"); + } + } + + ++ListSizeCur; + return *this; + } + }; + + typedef llvm::iterator_range<const_component_lists_iterator> + const_component_lists_range; + + /// \brief Iterators for all component lists. + const_component_lists_iterator component_lists_begin() const { + return const_component_lists_iterator( + getUniqueDeclsRef(), getDeclNumListsRef(), getComponentListSizesRef(), + getComponentsRef()); + } + const_component_lists_iterator component_lists_end() const { + return const_component_lists_iterator( + ArrayRef<ValueDecl *>(), ArrayRef<unsigned>(), ArrayRef<unsigned>(), + MappableExprComponentListRef(getComponentsRef().end(), + getComponentsRef().end())); + } + const_component_lists_range component_lists() const { + return {component_lists_begin(), component_lists_end()}; + } + + /// \brief Iterators for component lists associated with the provided + /// declaration. + const_component_lists_iterator + decl_component_lists_begin(const ValueDecl *VD) const { + return const_component_lists_iterator( + VD, getUniqueDeclsRef(), getDeclNumListsRef(), + getComponentListSizesRef(), getComponentsRef()); + } + const_component_lists_iterator decl_component_lists_end() const { + return component_lists_end(); + } + const_component_lists_range decl_component_lists(const ValueDecl *VD) const { + return {decl_component_lists_begin(VD), decl_component_lists_end()}; + } + + /// Iterators to access all the declarations, number of lists, list sizes, and + /// components. + typedef ArrayRef<ValueDecl *>::iterator const_all_decls_iterator; + typedef llvm::iterator_range<const_all_decls_iterator> const_all_decls_range; + const_all_decls_range all_decls() const { + auto A = getUniqueDeclsRef(); + return const_all_decls_range(A.begin(), A.end()); + } + + typedef ArrayRef<unsigned>::iterator const_all_num_lists_iterator; + typedef llvm::iterator_range<const_all_num_lists_iterator> + const_all_num_lists_range; + const_all_num_lists_range all_num_lists() const { + auto A = getDeclNumListsRef(); + return const_all_num_lists_range(A.begin(), A.end()); + } + + typedef ArrayRef<unsigned>::iterator const_all_lists_sizes_iterator; + typedef llvm::iterator_range<const_all_lists_sizes_iterator> + const_all_lists_sizes_range; + const_all_lists_sizes_range all_lists_sizes() const { + auto A = getComponentListSizesRef(); + return const_all_lists_sizes_range(A.begin(), A.end()); + } + + typedef ArrayRef<MappableComponent>::iterator const_all_components_iterator; + typedef llvm::iterator_range<const_all_components_iterator> + const_all_components_range; + const_all_components_range all_components() const { + auto A = getComponentsRef(); + return const_all_components_range(A.begin(), A.end()); + } +}; + /// \brief This represents clause 'map' in the '#pragma omp ...' /// directives. /// @@ -2783,12 +3272,27 @@ public: /// In this example directive '#pragma omp target' has clause 'map' /// with the variables 'a' and 'b'. /// -class OMPMapClause final : public OMPVarListClause<OMPMapClause>, - private llvm::TrailingObjects<OMPMapClause, Expr *> { +class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>, + private llvm::TrailingObjects< + OMPMapClause, Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent> { friend TrailingObjects; friend OMPVarListClause; + friend OMPMappableExprListClause; friend class OMPClauseReader; + /// Define the sizes of each trailing object array except the last one. This + /// is required for TrailingObjects to work properly. + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return varlist_size(); + } + size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { + return getUniqueDeclarationsNum(); + } + size_t numTrailingObjects(OverloadToken<unsigned>) const { + return getUniqueDeclarationsNum() + getTotalComponentListNum(); + } + /// \brief Map type modifier for the 'map' clause. OpenMPMapClauseKind MapTypeModifier; /// \brief Map type for the 'map' clause. @@ -2821,7 +3325,9 @@ class OMPMapClause final : public OMPVarListClause<OMPMapClause>, /// \brief Set colon location. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } - /// \brief Build clause with number of variables \a N. + /// \brief Build a clause for \a NumVars listed expressions, \a + /// NumUniqueDeclarations declarations, \a NumComponentLists total component + /// lists, and \a NumComponents total expression components. /// /// \param MapTypeModifier Map type modifier. /// \param MapType Map type. @@ -2829,25 +3335,37 @@ class OMPMapClause final : public OMPVarListClause<OMPMapClause>, /// \param MapLoc Location of the map type. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - /// \param N Number of the variables in the clause. + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. /// explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, SourceLocation MapLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, - unsigned N) - : OMPVarListClause<OMPMapClause>(OMPC_map, StartLoc, LParenLoc, EndLoc, - N), + unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc, + NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents), MapTypeModifier(MapTypeModifier), MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {} /// \brief Build an empty clause. /// - /// \param N Number of variables. - /// - explicit OMPMapClause(unsigned N) - : OMPVarListClause<OMPMapClause>(OMPC_map, SourceLocation(), - SourceLocation(), SourceLocation(), N), + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. + /// + explicit OMPMapClause(unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause( + OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(), + NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents), MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), MapTypeIsImplicit(false), MapLoc() {} @@ -2857,7 +3375,9 @@ public: /// \param C AST context. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - /// \param VL List of references to the variables. + /// \param Vars The original expression used in the clause. + /// \param Declarations Declarations used in the clause. + /// \param ComponentLists Component lists used in the clause. /// \param TypeModifier Map type modifier. /// \param Type Map type. /// \param TypeIsImplicit Map type is inferred implicitly. @@ -2865,16 +3385,28 @@ public: /// static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, - ArrayRef<Expr *> VL, + ArrayRef<Expr *> Vars, + ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc); - /// \brief Creates an empty clause with the place for \a N variables. + /// \brief Creates an empty clause with the place for for \a NumVars original + /// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists + /// lists, and \a NumComponents expression components. /// /// \param C AST context. - /// \param N The number of variables. - /// - static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned N); + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of unique base declarations in this + /// clause. + /// \param NumComponents Total number of expression components in the clause. + /// + static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents); /// \brief Fetches mapping kind for the clause. OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; } |

