}
};
+/// \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.
///
/// 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.
/// \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.
/// \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() {}
/// \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.
///
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; }
return new (Mem) OMPDependClause(N);
}
-OMPMapClause *OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL,
- OpenMPMapClauseKind TypeModifier,
- OpenMPMapClauseKind Type,
- bool TypeIsImplicit,
- SourceLocation TypeLoc) {
- void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
- OMPMapClause *Clause =
- new (Mem) OMPMapClause(TypeModifier, Type, TypeIsImplicit, TypeLoc,
- StartLoc, LParenLoc, EndLoc, VL.size());
- Clause->setVarRefs(VL);
+unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(
+ MappableExprComponentListsRef ComponentLists) {
+ unsigned TotalNum = 0u;
+ for (auto &C : ComponentLists)
+ TotalNum += C.size();
+ return TotalNum;
+}
+
+unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
+ ArrayRef<ValueDecl *> Declarations) {
+ unsigned TotalNum = 0u;
+ llvm::SmallPtrSet<const ValueDecl *, 8> Cache;
+ for (auto *D : Declarations) {
+ const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
+ if (Cache.count(VD))
+ continue;
+ ++TotalNum;
+ Cache.insert(VD);
+ }
+ return TotalNum;
+}
+
+OMPMapClause *
+OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists,
+ OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type,
+ bool TypeIsImplicit, SourceLocation TypeLoc) {
+
+ unsigned NumVars = Vars.size();
+ unsigned NumUniqueDeclarations =
+ getUniqueDeclarationsTotalNumber(Declarations);
+ unsigned NumComponentLists = ComponentLists.size();
+ unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
+
+ // We need to allocate:
+ // NumVars x Expr* - we have an original list expression for each clause list
+ // entry.
+ // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
+ // with each component list.
+ // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
+ // number of lists for each unique declaration and the size of each component
+ // list.
+ // NumComponents x MappableComponent - the total of all the components in all
+ // the lists.
+ void *Mem = C.Allocate(
+ totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
+ OMPClauseMappableExprCommon::MappableComponent>(
+ NumVars, NumUniqueDeclarations,
+ NumUniqueDeclarations + NumComponentLists, NumComponents));
+ OMPMapClause *Clause = new (Mem) OMPMapClause(
+ TypeModifier, Type, TypeIsImplicit, TypeLoc, StartLoc, LParenLoc, EndLoc,
+ NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents);
+
+ Clause->setVarRefs(Vars);
+ Clause->setClauseInfo(Declarations, ComponentLists);
Clause->setMapTypeModifier(TypeModifier);
Clause->setMapType(Type);
Clause->setMapLoc(TypeLoc);
return Clause;
}
-OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned N) {
- void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
- return new (Mem) OMPMapClause(N);
+OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned NumVars,
+ unsigned NumUniqueDeclarations,
+ unsigned NumComponentLists,
+ unsigned NumComponents) {
+ void *Mem = C.Allocate(
+ totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
+ OMPClauseMappableExprCommon::MappableComponent>(
+ NumVars, NumUniqueDeclarations,
+ NumUniqueDeclarations + NumComponentLists, NumComponents));
+ return new (Mem) OMPMapClause(NumVars, NumUniqueDeclarations,
+ NumComponentLists, NumComponents);
}
};
private:
- typedef SmallVector<Expr *, 4> MapInfo;
-
struct DSAInfo {
OpenMPClauseKind Attributes;
Expr *RefExpr;
typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy;
typedef std::pair<unsigned, VarDecl *> LCDeclInfo;
typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy;
- typedef llvm::DenseMap<ValueDecl *, MapInfo> MappedDeclsTy;
+ typedef llvm::DenseMap<
+ ValueDecl *, OMPClauseMappableExprCommon::MappableExprComponentLists>
+ MappedExprComponentsTy;
typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
CriticalsWithHintsTy;
struct SharingMapTy {
DeclSAMapTy SharingMap;
AlignedMapTy AlignedMap;
- MappedDeclsTy MappedDecls;
+ MappedExprComponentsTy MappedExprComponents;
LoopControlVariablesMapTy LCVMap;
DefaultDataSharingAttributes DefaultAttr;
SourceLocation DefaultAttrLoc;
Scope *getCurScope() { return Stack.back().CurScope; }
SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
- // Do the check specified in MapInfoCheck and return true if any issue is
- // found.
- template <class MapInfoCheck>
- bool checkMapInfoForVar(ValueDecl *VD, bool CurrentRegionOnly,
- MapInfoCheck Check) {
+ // Do the check specified in \a Check to all component lists and return true
+ // if any issue is found.
+ bool checkMappableExprComponentListsForDecl(
+ ValueDecl *VD, bool CurrentRegionOnly,
+ const llvm::function_ref<bool(
+ OMPClauseMappableExprCommon::MappableExprComponentListRef)> &Check) {
auto SI = Stack.rbegin();
auto SE = Stack.rend();
}
for (; SI != SE; ++SI) {
- auto MI = SI->MappedDecls.find(VD);
- if (MI != SI->MappedDecls.end()) {
- for (Expr *E : MI->second) {
- if (Check(E))
+ auto MI = SI->MappedExprComponents.find(VD);
+ if (MI != SI->MappedExprComponents.end())
+ for (auto &L : MI->second)
+ if (Check(L))
return true;
- }
- }
}
return false;
}
- void addExprToVarMapInfo(ValueDecl *VD, Expr *E) {
- if (Stack.size() > 1) {
- Stack.back().MappedDecls[VD].push_back(E);
- }
+ // Create a new mappable expression component list associated with a given
+ // declaration and initialize it with the provided list of components.
+ void addMappableExpressionComponents(
+ ValueDecl *VD,
+ OMPClauseMappableExprCommon::MappableExprComponentListRef Components) {
+ assert(Stack.size() > 1 &&
+ "Not expecting to retrieve components from a empty stack!");
+ auto &MEC = Stack.back().MappedExprComponents[VD];
+ // Create new entry and append the new components there.
+ MEC.resize(MEC.size() + 1);
+ MEC.back().append(Components.begin(), Components.end());
}
};
bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
// A list item cannot appear in both a map clause and a data-sharing
// attribute clause on the same construct
if (DSAStack->getCurrentDirective() == OMPD_target) {
- if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true,
- [&](Expr *RE) -> bool {return true;})) {
+ if (DSAStack->checkMappableExprComponentListsForDecl(
+ VD, /* CurrentRegionOnly = */ true,
+ [&](OMPClauseMappableExprCommon::MappableExprComponentListRef)
+ -> bool { return true; })) {
Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
<< getOpenMPClauseName(OMPC_private)
<< getOpenMPDirectiveName(DSAStack->getCurrentDirective());
// A list item cannot appear in both a map clause and a data-sharing
// attribute clause on the same construct
if (CurrDir == OMPD_target) {
- if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true,
- [&](Expr *RE) -> bool {return true;})) {
+ if (DSAStack->checkMappableExprComponentListsForDecl(
+ VD, /* CurrentRegionOnly = */ true,
+ [&](OMPClauseMappableExprCommon::MappableExprComponentListRef)
+ -> bool { return true; })) {
Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
<< getOpenMPClauseName(OMPC_firstprivate)
<< getOpenMPDirectiveName(DSAStack->getCurrentDirective());
// Return the expression of the base of the map clause or null if it cannot
// be determined and do all the necessary checks to see if the expression is
-// valid as a standalone map clause expression.
-static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) {
+// valid as a standalone map clause expression. In the process, record all the
+// components of the expression.
+static Expr *CheckMapClauseExpressionBase(
+ Sema &SemaRef, Expr *E,
+ OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents) {
SourceLocation ELoc = E->getExprLoc();
SourceRange ERange = E->getSourceRange();
// section before that.
AllowUnitySizeArraySection = false;
AllowWholeSizeArraySection = false;
+
+ // Record the component.
+ CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent(
+ CurE, CurE->getDecl()));
continue;
}
//
AllowUnitySizeArraySection = false;
AllowWholeSizeArraySection = false;
+
+ // Record the component.
+ CurComponents.push_back(
+ OMPClauseMappableExprCommon::MappableComponent(CurE, FD));
continue;
}
if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
E->getType()))
AllowWholeSizeArraySection = false;
+
+ // Record the component - we don't have any declaration associated.
+ CurComponents.push_back(
+ OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr));
continue;
}
<< CurE->getSourceRange();
break;
}
+
+ // Record the component - we don't have any declaration associated.
+ CurComponents.push_back(
+ OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr));
continue;
}
// Return true if expression E associated with value VD has conflicts with other
// map information.
-static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD,
- Expr *E, bool CurrentRegionOnly) {
+static bool CheckMapConflicts(
+ Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E,
+ bool CurrentRegionOnly,
+ OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents) {
assert(VD && E);
-
- // Types used to organize the components of a valid map clause.
- typedef std::pair<Expr *, ValueDecl *> MapExpressionComponent;
- typedef SmallVector<MapExpressionComponent, 4> MapExpressionComponents;
-
- // Helper to extract the components in the map clause expression E and store
- // them into MEC. This assumes that E is a valid map clause expression, i.e.
- // it has already passed the single clause checks.
- auto ExtractMapExpressionComponents = [](Expr *TE,
- MapExpressionComponents &MEC) {
- while (true) {
- TE = TE->IgnoreParenImpCasts();
-
- if (auto *CurE = dyn_cast<DeclRefExpr>(TE)) {
- MEC.push_back(
- MapExpressionComponent(CurE, cast<VarDecl>(CurE->getDecl())));
- break;
- }
-
- if (auto *CurE = dyn_cast<MemberExpr>(TE)) {
- auto *BaseE = CurE->getBase()->IgnoreParenImpCasts();
-
- MEC.push_back(MapExpressionComponent(
- CurE, cast<FieldDecl>(CurE->getMemberDecl())));
- if (isa<CXXThisExpr>(BaseE))
- break;
-
- TE = BaseE;
- continue;
- }
-
- if (auto *CurE = dyn_cast<ArraySubscriptExpr>(TE)) {
- MEC.push_back(MapExpressionComponent(CurE, nullptr));
- TE = CurE->getBase()->IgnoreParenImpCasts();
- continue;
- }
-
- if (auto *CurE = dyn_cast<OMPArraySectionExpr>(TE)) {
- MEC.push_back(MapExpressionComponent(CurE, nullptr));
- TE = CurE->getBase()->IgnoreParenImpCasts();
- continue;
- }
-
- llvm_unreachable(
- "Expecting only valid map clause expressions at this point!");
- }
- };
-
SourceLocation ELoc = E->getExprLoc();
SourceRange ERange = E->getSourceRange();
// the expression under test with the components of the expressions that are
// already in the stack.
- MapExpressionComponents CurComponents;
- ExtractMapExpressionComponents(E, CurComponents);
-
assert(!CurComponents.empty() && "Map clause expression with no components!");
- assert(CurComponents.back().second == VD &&
+ assert(CurComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!");
// Variables to help detecting enclosing problems in data environment nests.
bool IsEnclosedByDataEnvironmentExpr = false;
- Expr *EnclosingExpr = nullptr;
+ const Expr *EnclosingExpr = nullptr;
+
+ bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
+ VD, CurrentRegionOnly,
+ [&](OMPClauseMappableExprCommon::MappableExprComponentListRef
+ StackComponents) -> bool {
- bool FoundError =
- DSAS->checkMapInfoForVar(VD, CurrentRegionOnly, [&](Expr *RE) -> bool {
- MapExpressionComponents StackComponents;
- ExtractMapExpressionComponents(RE, StackComponents);
assert(!StackComponents.empty() &&
"Map clause expression with no components!");
- assert(StackComponents.back().second == VD &&
+ assert(StackComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!");
+ // The whole expression in the stack.
+ auto *RE = StackComponents.front().getAssociatedExpression();
+
// Expressions must start from the same base. Here we detect at which
// point both expressions diverge from each other and see if we can
// detect if the memory referred to both expressions is contiguous and
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
// At most one list item can be an array item derived from a given
// variable in map clauses of the same construct.
- if (CurrentRegionOnly && (isa<ArraySubscriptExpr>(CI->first) ||
- isa<OMPArraySectionExpr>(CI->first)) &&
- (isa<ArraySubscriptExpr>(SI->first) ||
- isa<OMPArraySectionExpr>(SI->first))) {
- SemaRef.Diag(CI->first->getExprLoc(),
+ if (CurrentRegionOnly &&
+ (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
+ isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
+ (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
+ isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
+ SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
diag::err_omp_multiple_array_items_in_map_clause)
- << CI->first->getSourceRange();
- ;
- SemaRef.Diag(SI->first->getExprLoc(), diag::note_used_here)
- << SI->first->getSourceRange();
+ << CI->getAssociatedExpression()->getSourceRange();
+ SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
+ diag::note_used_here)
+ << SI->getAssociatedExpression()->getSourceRange();
return true;
}
// Do both expressions have the same kind?
- if (CI->first->getStmtClass() != SI->first->getStmtClass())
+ if (CI->getAssociatedExpression()->getStmtClass() !=
+ SI->getAssociatedExpression()->getStmtClass())
break;
// Are we dealing with different variables/fields?
- if (CI->second != SI->second)
+ if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
break;
}
}
}
- QualType DerivedType = std::prev(CI)->first->getType();
- SourceLocation DerivedLoc = std::prev(CI)->first->getExprLoc();
+ QualType DerivedType =
+ std::prev(CI)->getAssociatedDeclaration()->getType();
+ SourceLocation DerivedLoc =
+ std::prev(CI)->getAssociatedExpression()->getExprLoc();
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
// If the type of a list item is a reference to a type T then the type
// will be considered to be T for all purposes of this clause.
- if (DerivedType->isReferenceType())
- DerivedType = DerivedType->getPointeeType();
+ DerivedType = DerivedType.getNonReferenceType();
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
// A variable for which the type is pointer and an array section
}
// The current expression uses the same base as other expression in the
- // data environment but does not contain it completelly.
+ // data environment but does not contain it completely.
if (!CurrentRegionOnly && SI != SE)
EnclosingExpr = RE;
// If a list item is an element of a structure, and a different element of
// the structure has a corresponding list item in the device data environment
// prior to a task encountering the construct associated with the map clause,
- // then the list item must also have a correspnding list item in the device
+ // then the list item must also have a corresponding list item in the device
// data environment prior to the task encountering the construct.
//
if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
SourceLocation LParenLoc, SourceLocation EndLoc) {
SmallVector<Expr *, 4> Vars;
+ // Keep track of the mappable components and base declarations in this clause.
+ // Each entry in the list is going to have a list of components associated. We
+ // record each set of the components so that we can build the clause later on.
+ // In the end we should have the same amount of declarations and component
+ // lists.
+ OMPClauseMappableExprCommon::MappableExprComponentLists ClauseComponents;
+ SmallVector<ValueDecl *, 16> ClauseBaseDeclarations;
+
+ ClauseComponents.reserve(VarList.size());
+ ClauseBaseDeclarations.reserve(VarList.size());
+
for (auto &RE : VarList) {
assert(RE && "Null expr in omp map");
if (isa<DependentScopeDeclRefExpr>(RE)) {
continue;
}
- // Obtain the array or member expression bases if required.
- auto *BE = CheckMapClauseExpressionBase(*this, SimpleExpr);
+ OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
+ ValueDecl *CurDeclaration = nullptr;
+
+ // Obtain the array or member expression bases if required. Also, fill the
+ // components array with all the components identified in the process.
+ auto *BE = CheckMapClauseExpressionBase(*this, SimpleExpr, CurComponents);
if (!BE)
continue;
- // If the base is a reference to a variable, we rely on that variable for
- // the following checks. If it is a 'this' expression we rely on the field.
- ValueDecl *D = nullptr;
- if (auto *DRE = dyn_cast<DeclRefExpr>(BE)) {
- D = DRE->getDecl();
- } else {
- auto *ME = cast<MemberExpr>(BE);
- assert(isa<CXXThisExpr>(ME->getBase()) && "Unexpected expression!");
- D = ME->getMemberDecl();
- }
- assert(D && "Null decl on map clause.");
+ assert(!CurComponents.empty() &&
+ "Invalid mappable expression information.");
- auto *VD = dyn_cast<VarDecl>(D);
- auto *FD = dyn_cast<FieldDecl>(D);
+ // For the following checks, we rely on the base declaration which is
+ // expected to be associated with the last component. The declaration is
+ // expected to be a variable or a field (if 'this' is being mapped).
+ CurDeclaration = CurComponents.back().getAssociatedDeclaration();
+ assert(CurDeclaration && "Null decl on map clause.");
+ assert(
+ CurDeclaration->isCanonicalDecl() &&
+ "Expecting components to have associated only canonical declarations.");
+
+ auto *VD = dyn_cast<VarDecl>(CurDeclaration);
+ auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
assert((VD || FD) && "Only variables or fields are expected here!");
(void)FD;
// Check conflicts with other map clause expressions. We check the conflicts
// with the current construct separately from the enclosing data
// environment, because the restrictions are different.
- if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr,
- /*CurrentRegionOnly=*/true))
+ if (CheckMapConflicts(*this, DSAStack, CurDeclaration, SimpleExpr,
+ /*CurrentRegionOnly=*/true, CurComponents))
break;
- if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr,
- /*CurrentRegionOnly=*/false))
+ if (CheckMapConflicts(*this, DSAStack, CurDeclaration, SimpleExpr,
+ /*CurrentRegionOnly=*/false, CurComponents))
break;
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
// If the type of a list item is a reference to a type T then the type will
// be considered to be T for all purposes of this clause.
- QualType Type = D->getType();
- if (Type->isReferenceType())
- Type = Type->getPointeeType();
+ QualType Type = CurDeclaration->getType().getNonReferenceType();
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
// A list item must have a mappable type.
Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
<< getOpenMPClauseName(DVar.CKind)
<< getOpenMPDirectiveName(DSAStack->getCurrentDirective());
- ReportOriginalDSA(*this, DSAStack, D, DVar);
+ ReportOriginalDSA(*this, DSAStack, CurDeclaration, DVar);
continue;
}
}
+ // Save the current expression.
Vars.push_back(RE);
- DSAStack->addExprToVarMapInfo(D, RE);
+
+ // Store the components in the stack so that they can be used to check
+ // against other clauses later on.
+ DSAStack->addMappableExpressionComponents(CurDeclaration, CurComponents);
+
+ // Save the components and declaration to create the clause. For purposes of
+ // the clause creation, any component list that has has base 'this' uses
+ // null has
+ ClauseComponents.resize(ClauseComponents.size() + 1);
+ ClauseComponents.back().append(CurComponents.begin(), CurComponents.end());
+ ClauseBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
+ : CurDeclaration);
}
// We need to produce a map clause even if we don't have variables so that
// other diagnostics related with non-existing map clauses are accurate.
- return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
- MapTypeModifier, MapType, IsMapTypeImplicit,
- MapLoc);
+ return OMPMapClause::Create(
+ Context, StartLoc, LParenLoc, EndLoc, Vars, ClauseBaseDeclarations,
+ ClauseComponents, MapTypeModifier, MapType, IsMapTypeImplicit, MapLoc);
}
QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
case OMPC_device:
C = new (Context) OMPDeviceClause();
break;
- case OMPC_map:
- C = OMPMapClause::CreateEmpty(Context, Record[Idx++]);
+ case OMPC_map: {
+ unsigned NumVars = Record[Idx++];
+ unsigned NumDeclarations = Record[Idx++];
+ unsigned NumLists = Record[Idx++];
+ unsigned NumComponents = Record[Idx++];
+ C = OMPMapClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
+ NumComponents);
break;
+ }
case OMPC_num_teams:
C = new (Context) OMPNumTeamsClause();
break;
C->setMapLoc(Reader->ReadSourceLocation(Record, Idx));
C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
auto NumVars = C->varlist_size();
+ auto UniqueDecls = C->getUniqueDeclarationsNum();
+ auto TotalLists = C->getTotalComponentListNum();
+ auto TotalComponents = C->getTotalComponentsNum();
+
SmallVector<Expr *, 16> Vars;
Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i) {
+ for (unsigned i = 0; i != NumVars; ++i)
Vars.push_back(Reader->Reader.ReadSubExpr());
- }
C->setVarRefs(Vars);
+
+ SmallVector<ValueDecl *, 16> Decls;
+ Decls.reserve(UniqueDecls);
+ for (unsigned i = 0; i < UniqueDecls; ++i)
+ Decls.push_back(
+ Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx));
+ C->setUniqueDecls(Decls);
+
+ SmallVector<unsigned, 16> ListsPerDecl;
+ ListsPerDecl.reserve(UniqueDecls);
+ for (unsigned i = 0; i < UniqueDecls; ++i)
+ ListsPerDecl.push_back(Record[Idx++]);
+ C->setDeclNumLists(ListsPerDecl);
+
+ SmallVector<unsigned, 32> ListSizes;
+ ListSizes.reserve(TotalLists);
+ for (unsigned i = 0; i < TotalLists; ++i)
+ ListSizes.push_back(Record[Idx++]);
+ C->setComponentListSizes(ListSizes);
+
+ SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
+ Components.reserve(TotalComponents);
+ for (unsigned i = 0; i < TotalComponents; ++i) {
+ Expr *AssociatedExpr = Reader->Reader.ReadSubExpr();
+ ValueDecl *AssociatedDecl =
+ Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx);
+ Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
+ AssociatedExpr, AssociatedDecl));
+ }
+ C->setComponents(Components, ListSizes);
}
void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
Record.push_back(C->varlist_size());
+ Record.push_back(C->getUniqueDeclarationsNum());
+ Record.push_back(C->getTotalComponentListNum());
+ Record.push_back(C->getTotalComponentsNum());
Record.AddSourceLocation(C->getLParenLoc());
Record.push_back(C->getMapTypeModifier());
Record.push_back(C->getMapType());
Record.AddSourceLocation(C->getMapLoc());
Record.AddSourceLocation(C->getColonLoc());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
+ for (auto *E : C->varlists())
+ Record.AddStmt(E);
+ for (auto *D : C->all_decls())
+ Record.AddDeclRef(D);
+ for (auto N : C->all_num_lists())
+ Record.push_back(N);
+ for (auto N : C->all_lists_sizes())
+ Record.push_back(N);
+ for (auto &M : C->all_components()) {
+ Record.AddStmt(M.getAssociatedExpression());
+ Record.AddDeclRef(M.getAssociatedDeclaration());
+ }
}
void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {