diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/OpenMPClause.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Basic/OpenMPKinds.cpp | 11 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 65 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 168 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 43 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 16 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 5 |
8 files changed, 199 insertions, 138 deletions
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 3124b0ff6f5..76098f15bf3 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -796,8 +796,10 @@ 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) { + ArrayRef<OpenMPMapModifierKind> MapModifiers, + ArrayRef<SourceLocation> MapModifiersLoc, + OpenMPMapClauseKind Type, bool TypeIsImplicit, + SourceLocation TypeLoc) { unsigned NumVars = Vars.size(); unsigned NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations); @@ -820,12 +822,12 @@ OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, NumVars, NumUniqueDeclarations, NumUniqueDeclarations + NumComponentLists, NumComponents)); OMPMapClause *Clause = new (Mem) OMPMapClause( - TypeModifier, Type, TypeIsImplicit, TypeLoc, StartLoc, LParenLoc, EndLoc, - NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents); + MapModifiers, MapModifiersLoc, 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; @@ -1426,10 +1428,12 @@ void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) { if (!Node->varlist_empty()) { OS << "map("; if (Node->getMapType() != OMPC_MAP_unknown) { - if (Node->getMapTypeModifier() != OMPC_MAP_unknown) { - OS << getOpenMPSimpleClauseTypeName(OMPC_map, - Node->getMapTypeModifier()); - OS << ','; + for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) { + OS << getOpenMPSimpleClauseTypeName(OMPC_map, + Node->getMapTypeModifier(I)); + OS << ','; + } } OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType()); OS << ':'; diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index dcd36c456fd..a5bfac86e61 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -108,8 +108,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_LINEAR_unknown); case OMPC_map: - return llvm::StringSwitch<OpenMPMapClauseKind>(Str) -#define OPENMP_MAP_KIND(Name) .Case(#Name, OMPC_MAP_##Name) + return llvm::StringSwitch<unsigned>(Str) +#define OPENMP_MAP_KIND(Name) \ + .Case(#Name, static_cast<unsigned>(OMPC_MAP_##Name)) +#define OPENMP_MAP_MODIFIER_KIND(Name) \ + .Case(#Name, static_cast<unsigned>(OMPC_MAP_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_MAP_unknown); case OMPC_dist_schedule: @@ -243,10 +246,14 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_map: switch (Type) { case OMPC_MAP_unknown: + case OMPC_MAP_MODIFIER_last: return "unknown"; #define OPENMP_MAP_KIND(Name) \ case OMPC_MAP_##Name: \ return #Name; +#define OPENMP_MAP_MODIFIER_KIND(Name) \ + case OMPC_MAP_MODIFIER_##Name: \ + return #Name; #include "clang/Basic/OpenMPKinds.def" default: break; diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 66f0783e27d..d7a0a72de10 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -6645,17 +6645,17 @@ private: struct MapInfo { OMPClauseMappableExprCommon::MappableExprComponentListRef Components; OpenMPMapClauseKind MapType = OMPC_MAP_unknown; - OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown; + ArrayRef<OpenMPMapModifierKind> MapModifiers; bool ReturnDevicePointer = false; bool IsImplicit = false; MapInfo() = default; MapInfo( OMPClauseMappableExprCommon::MappableExprComponentListRef Components, - OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapTypeModifier, + OpenMPMapClauseKind MapType, + ArrayRef<OpenMPMapModifierKind> MapModifiers, bool ReturnDevicePointer, bool IsImplicit) - : Components(Components), MapType(MapType), - MapTypeModifier(MapTypeModifier), + : Components(Components), MapType(MapType), MapModifiers(MapModifiers), ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit) {} }; @@ -6732,10 +6732,9 @@ private: /// a flag marking the map as a pointer if requested. Add a flag marking the /// map as the first one of a series of maps that relate to the same map /// expression. - OpenMPOffloadMappingFlags getMapTypeBits(OpenMPMapClauseKind MapType, - OpenMPMapClauseKind MapTypeModifier, - bool IsImplicit, bool AddPtrFlag, - bool AddIsTargetParamFlag) const { + OpenMPOffloadMappingFlags getMapTypeBits( + OpenMPMapClauseKind MapType, ArrayRef<OpenMPMapModifierKind> MapModifiers, + bool IsImplicit, bool AddPtrFlag, bool AddIsTargetParamFlag) const { OpenMPOffloadMappingFlags Bits = IsImplicit ? OMP_MAP_IMPLICIT : OMP_MAP_NONE; switch (MapType) { @@ -6758,7 +6757,6 @@ private: case OMPC_MAP_delete: Bits |= OMP_MAP_DELETE; break; - case OMPC_MAP_always: case OMPC_MAP_unknown: llvm_unreachable("Unexpected map type!"); } @@ -6766,7 +6764,8 @@ private: Bits |= OMP_MAP_PTR_AND_OBJ; if (AddIsTargetParamFlag) Bits |= OMP_MAP_TARGET_PARAM; - if (MapTypeModifier == OMPC_MAP_always) + if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_always) + != MapModifiers.end()) Bits |= OMP_MAP_ALWAYS; return Bits; } @@ -6815,7 +6814,8 @@ private: /// \a IsFirstComponent should be set to true if the provided set of /// components is the first associated with a capture. void generateInfoForComponentList( - OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapTypeModifier, + OpenMPMapClauseKind MapType, + ArrayRef<OpenMPMapModifierKind> MapModifiers, OMPClauseMappableExprCommon::MappableExprComponentListRef Components, MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types, @@ -7125,7 +7125,7 @@ private: // Emit data for non-overlapped data. OpenMPOffloadMappingFlags Flags = OMP_MAP_MEMBER_OF | - getMapTypeBits(MapType, MapTypeModifier, IsImplicit, + getMapTypeBits(MapType, MapModifiers, IsImplicit, /*AddPtrFlag=*/false, /*AddIsTargetParamFlag=*/false); LB = BP; @@ -7175,7 +7175,7 @@ private: // this map is the first one that relates with the current capture // (there is a set of entries for each capture). OpenMPOffloadMappingFlags Flags = getMapTypeBits( - MapType, MapTypeModifier, IsImplicit, + MapType, MapModifiers, IsImplicit, !IsExpressionFirstInfo || IsLink, IsCaptureFirstInfo && !IsLink); if (!IsExpressionFirstInfo) { @@ -7395,28 +7395,29 @@ public: auto &&InfoGen = [&Info]( const ValueDecl *D, OMPClauseMappableExprCommon::MappableExprComponentListRef L, - OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapModifier, + OpenMPMapClauseKind MapType, + ArrayRef<OpenMPMapModifierKind> MapModifiers, bool ReturnDevicePointer, bool IsImplicit) { const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr; - Info[VD].emplace_back(L, MapType, MapModifier, ReturnDevicePointer, + Info[VD].emplace_back(L, MapType, MapModifiers, ReturnDevicePointer, IsImplicit); }; // FIXME: MSVC 2013 seems to require this-> to find member CurDir. for (const auto *C : this->CurDir.getClausesOfKind<OMPMapClause>()) for (const auto &L : C->component_lists()) { - InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifier(), + InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifiers(), /*ReturnDevicePointer=*/false, C->isImplicit()); } for (const auto *C : this->CurDir.getClausesOfKind<OMPToClause>()) for (const auto &L : C->component_lists()) { - InfoGen(L.first, L.second, OMPC_MAP_to, OMPC_MAP_unknown, + InfoGen(L.first, L.second, OMPC_MAP_to, llvm::None, /*ReturnDevicePointer=*/false, C->isImplicit()); } for (const auto *C : this->CurDir.getClausesOfKind<OMPFromClause>()) for (const auto &L : C->component_lists()) { - InfoGen(L.first, L.second, OMPC_MAP_from, OMPC_MAP_unknown, + InfoGen(L.first, L.second, OMPC_MAP_from, llvm::None, /*ReturnDevicePointer=*/false, C->isImplicit()); } @@ -7469,7 +7470,7 @@ public: // Nonetheless, generateInfoForComponentList must be called to take // the pointer into account for the calculation of the range of the // partial struct. - InfoGen(nullptr, L.second, OMPC_MAP_unknown, OMPC_MAP_unknown, + InfoGen(nullptr, L.second, OMPC_MAP_unknown, llvm::None, /*ReturnDevicePointer=*/false, C->isImplicit()); DeferredInfo[nullptr].emplace_back(IE, VD); } else { @@ -7503,7 +7504,7 @@ public: unsigned CurrentBasePointersIdx = CurBasePointers.size(); // FIXME: MSVC 2013 seems to require this-> to find the member method. this->generateInfoForComponentList( - L.MapType, L.MapTypeModifier, L.Components, CurBasePointers, + L.MapType, L.MapModifiers, L.Components, CurBasePointers, CurPointers, CurSizes, CurTypes, PartialStruct, IsFirstComponentList, L.IsImplicit); @@ -7662,7 +7663,7 @@ public: using MapData = std::tuple<OMPClauseMappableExprCommon::MappableExprComponentListRef, - OpenMPMapClauseKind, OpenMPMapClauseKind, bool>; + OpenMPMapClauseKind, ArrayRef<OpenMPMapModifierKind>, bool>; SmallVector<MapData, 4> DeclComponentLists; // FIXME: MSVC 2013 seems to require this-> to find member CurDir. for (const auto *C : this->CurDir.getClausesOfKind<OMPMapClause>()) { @@ -7672,7 +7673,7 @@ public: assert(!L.second.empty() && "Not expecting declaration with no component lists."); DeclComponentLists.emplace_back(L.second, C->getMapType(), - C->getMapTypeModifier(), + C->getMapTypeModifiers(), C->isImplicit()); } } @@ -7688,13 +7689,13 @@ public: for (const MapData &L : DeclComponentLists) { OMPClauseMappableExprCommon::MappableExprComponentListRef Components; OpenMPMapClauseKind MapType; - OpenMPMapClauseKind MapTypeModifier; + ArrayRef<OpenMPMapModifierKind> MapModifiers; bool IsImplicit; - std::tie(Components, MapType, MapTypeModifier, IsImplicit) = L; + std::tie(Components, MapType, MapModifiers, IsImplicit) = L; ++Count; for (const MapData &L1 : makeArrayRef(DeclComponentLists).slice(Count)) { OMPClauseMappableExprCommon::MappableExprComponentListRef Components1; - std::tie(Components1, MapType, MapTypeModifier, IsImplicit) = L1; + std::tie(Components1, MapType, MapModifiers, IsImplicit) = L1; auto CI = Components.rbegin(); auto CE = Components.rend(); auto SI = Components1.rbegin(); @@ -7778,13 +7779,13 @@ public: const MapData &L = *Pair.getFirst(); OMPClauseMappableExprCommon::MappableExprComponentListRef Components; OpenMPMapClauseKind MapType; - OpenMPMapClauseKind MapTypeModifier; + ArrayRef<OpenMPMapModifierKind> MapModifiers; bool IsImplicit; - std::tie(Components, MapType, MapTypeModifier, IsImplicit) = L; + std::tie(Components, MapType, MapModifiers, IsImplicit) = L; ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef> OverlappedComponents = Pair.getSecond(); bool IsFirstComponentList = true; - generateInfoForComponentList(MapType, MapTypeModifier, Components, + generateInfoForComponentList(MapType, MapModifiers, Components, BasePointers, Pointers, Sizes, Types, PartialStruct, IsFirstComponentList, IsImplicit, OverlappedComponents); @@ -7794,12 +7795,12 @@ public: for (const MapData &L : DeclComponentLists) { OMPClauseMappableExprCommon::MappableExprComponentListRef Components; OpenMPMapClauseKind MapType; - OpenMPMapClauseKind MapTypeModifier; + ArrayRef<OpenMPMapModifierKind> MapModifiers; bool IsImplicit; - std::tie(Components, MapType, MapTypeModifier, IsImplicit) = L; + std::tie(Components, MapType, MapModifiers, IsImplicit) = L; auto It = OverlappedData.find(&L); if (It == OverlappedData.end()) - generateInfoForComponentList(MapType, MapTypeModifier, Components, + generateInfoForComponentList(MapType, MapModifiers, Components, BasePointers, Pointers, Sizes, Types, PartialStruct, IsFirstComponentList, IsImplicit); @@ -7828,7 +7829,7 @@ public: continue; StructRangeInfoTy PartialStruct; generateInfoForComponentList( - C->getMapType(), C->getMapTypeModifier(), L.second, BasePointers, + C->getMapType(), C->getMapTypeModifiers(), L.second, BasePointers, Pointers, Sizes, Types, PartialStruct, /*IsFirstComponentList=*/true, C->isImplicit()); assert(!PartialStruct.Base.isValid() && diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 1fb52801a9e..17c3fa3cf2a 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1774,6 +1774,79 @@ static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, nullptr, nullptr, ReductionId); } +/// Checks if the token is a valid map-type-modifier. +static OpenMPMapModifierKind isMapModifier(Parser &P) { + Token Tok = P.getCurToken(); + if (!Tok.is(tok::identifier)) + return OMPC_MAP_MODIFIER_unknown; + + Preprocessor &PP = P.getPreprocessor(); + OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>( + getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok))); + return TypeModifier; +} + +/// Parse map-type-modifiers in map clause. +/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) +/// where, map-type-modifier ::= always | close +static void parseMapTypeModifiers(Parser &P, + Parser::OpenMPVarListDataTy &Data) { + Preprocessor &PP = P.getPreprocessor(); + while (P.getCurToken().isNot(tok::colon)) { + Token Tok = P.getCurToken(); + OpenMPMapModifierKind TypeModifier = isMapModifier(P); + if (TypeModifier == OMPC_MAP_MODIFIER_always || + TypeModifier == OMPC_MAP_MODIFIER_close) { + Data.MapTypeModifiers.push_back(TypeModifier); + Data.MapTypeModifiersLoc.push_back(Tok.getLocation()); + P.ConsumeToken(); + } else { + // For the case of unknown map-type-modifier or a map-type. + // Map-type is followed by a colon; the function returns when it + // encounters a token followed by a colon. + if (Tok.is(tok::comma)) { + P.Diag(Tok, diag::err_omp_map_type_modifier_missing); + P.ConsumeToken(); + continue; + } + // Potential map-type token as it is followed by a colon. + if (PP.LookAhead(0).is(tok::colon)) + return; + P.Diag(Tok, diag::err_omp_unknown_map_type_modifier); + P.ConsumeToken(); + } + if (P.getCurToken().is(tok::comma)) + P.ConsumeToken(); + } +} + +/// Checks if the token is a valid map-type. +static OpenMPMapClauseKind isMapType(Parser &P) { + Token Tok = P.getCurToken(); + // The map-type token can be either an identifier or the C++ delete keyword. + if (!Tok.isOneOf(tok::identifier, tok::kw_delete)) + return OMPC_MAP_unknown; + Preprocessor &PP = P.getPreprocessor(); + OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>( + getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok))); + return MapType; +} + +/// Parse map-type in map clause. +/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) +/// where, map-type ::= to | from | tofrom | alloc | release | delete +static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) { + Token Tok = P.getCurToken(); + if (Tok.is(tok::colon)) { + P.Diag(Tok, diag::err_omp_map_type_missing); + return; + } + Data.MapType = isMapType(P); + if (Data.MapType == OMPC_MAP_unknown) + P.Diag(Tok, diag::err_omp_unknown_map_type); + P.ConsumeToken(); +} + /// Parses clauses with list. bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, @@ -1852,82 +1925,27 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, // Handle map type for map clause. ColonProtectionRAIIObject ColonRAII(*this); - /// The map clause modifier token can be either a identifier or the C++ - /// delete keyword. - auto &&IsMapClauseModifierToken = [](const Token &Tok) -> bool { - return Tok.isOneOf(tok::identifier, tok::kw_delete); - }; - // The first identifier may be a list item, a map-type or a - // map-type-modifier. The map modifier can also be delete which has the same + // map-type-modifier. The map-type can also be delete which has the same // spelling of the C++ delete keyword. - Data.MapType = - IsMapClauseModifierToken(Tok) - ? static_cast<OpenMPMapClauseKind>( - getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) - : OMPC_MAP_unknown; Data.DepLinMapLoc = Tok.getLocation(); - if (IsMapClauseModifierToken(Tok)) { - if (PP.LookAhead(0).is(tok::colon)) { - if (Data.MapType == OMPC_MAP_unknown) - Diag(Tok, diag::err_omp_unknown_map_type); - else if (Data.MapType == OMPC_MAP_always) - Diag(Tok, diag::err_omp_map_type_missing); - ConsumeToken(); - } else if (PP.LookAhead(0).is(tok::comma)) { - if (IsMapClauseModifierToken(PP.LookAhead(1)) && - PP.LookAhead(2).is(tok::colon)) { - Data.MapTypeModifier = Data.MapType; - if (Data.MapTypeModifier != OMPC_MAP_always) { - Diag(Tok, diag::err_omp_unknown_map_type_modifier); - Data.MapTypeModifier = OMPC_MAP_unknown; - } - - ConsumeToken(); - ConsumeToken(); - - Data.MapType = - IsMapClauseModifierToken(Tok) - ? static_cast<OpenMPMapClauseKind>( - getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) - : OMPC_MAP_unknown; - if (Data.MapType == OMPC_MAP_unknown || - Data.MapType == OMPC_MAP_always) - Diag(Tok, diag::err_omp_unknown_map_type); - ConsumeToken(); - } else { - Data.MapType = OMPC_MAP_tofrom; - Data.IsMapTypeImplicit = true; - } - } else if (IsMapClauseModifierToken(PP.LookAhead(0))) { - if (PP.LookAhead(1).is(tok::colon)) { - Data.MapTypeModifier = Data.MapType; - if (Data.MapTypeModifier != OMPC_MAP_always) { - Diag(Tok, diag::err_omp_unknown_map_type_modifier); - Data.MapTypeModifier = OMPC_MAP_unknown; - } - - ConsumeToken(); - - Data.MapType = - IsMapClauseModifierToken(Tok) - ? static_cast<OpenMPMapClauseKind>( - getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) - : OMPC_MAP_unknown; - if (Data.MapType == OMPC_MAP_unknown || - Data.MapType == OMPC_MAP_always) - Diag(Tok, diag::err_omp_unknown_map_type); - ConsumeToken(); - } else { - Data.MapType = OMPC_MAP_tofrom; - Data.IsMapTypeImplicit = true; - } - } else { - Data.MapType = OMPC_MAP_tofrom; - Data.IsMapTypeImplicit = true; - } - } else { + // Check for presence of a colon in the map clause. + TentativeParsingAction TPA(*this); + bool ColonPresent = false; + if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch)) { + if (Tok.is(tok::colon)) + ColonPresent = true; + } + TPA.Revert(); + // Only parse map-type-modifier[s] and map-type if a colon is present in + // the map clause. + if (ColonPresent) { + parseMapTypeModifiers(*this, Data); + parseMapType(*this, Data); + } + if (Data.MapType == OMPC_MAP_unknown) { Data.MapType = OMPC_MAP_tofrom; Data.IsMapTypeImplicit = true; } @@ -2025,7 +2043,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /// depend-clause: /// 'depend' '(' in | out | inout : list | source ')' /// map-clause: -/// 'map' '(' [ [ always , ] +/// 'map' '(' [ [ always [,] ] [ close [,] ] /// to | from | tofrom | alloc | release | delete ':' ] list ')'; /// to-clause: /// 'to' '(' list ')' @@ -2056,7 +2074,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, return Actions.ActOnOpenMPVarListClause( Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Data.RLoc, Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind, - Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit, - Data.DepLinMapLoc); + Data.MapTypeModifiers, Data.MapTypeModifiersLoc, Data.MapType, + Data.IsMapTypeImplicit, Data.DepLinMapLoc); } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 2daf45411ec..38a329a1fdf 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3336,9 +3336,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( } if (!ImplicitMaps.empty()) { if (OMPClause *Implicit = ActOnOpenMPMapClause( - OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, - SourceLocation(), SourceLocation(), ImplicitMaps, - SourceLocation(), SourceLocation(), SourceLocation())) { + llvm::None, llvm::None, OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), + ImplicitMaps, SourceLocation(), SourceLocation(), + SourceLocation())) { ClausesWithImplicit.emplace_back(Implicit); ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); @@ -9535,7 +9536,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause( SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, - OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, + OpenMPLinearClauseKind LinKind, + ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, + ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { OMPClause *Res = nullptr; @@ -9588,9 +9591,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause( StartLoc, LParenLoc, EndLoc); break; case OMPC_map: - Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, - DepLinMapLoc, ColonLoc, VarList, StartLoc, - LParenLoc, EndLoc); + Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, MapType, + IsMapTypeImplicit, DepLinMapLoc, ColonLoc, + VarList, StartLoc, LParenLoc, EndLoc); break; case OMPC_to: Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); @@ -12957,7 +12960,8 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, } OMPClause * -Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, +Sema::ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, + ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc, @@ -12966,12 +12970,31 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, MapType, IsMapTypeImplicit); + OpenMPMapModifierKind Modifiers[] = { OMPC_MAP_MODIFIER_unknown, + OMPC_MAP_MODIFIER_unknown }; + SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; + + // Process map-type-modifiers, flag errors for duplicate modifiers. + unsigned Count = 0; + for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { + if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && + llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { + Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); + continue; + } + assert(Count < OMPMapClause::NumberOfModifiers && + "Modifiers exceed the allowed number of map type modifiers"); + Modifiers[Count] = MapTypeModifiers[I]; + ModifiersLoc[Count] = MapTypeModifiersLoc[I]; + ++Count; + } + // 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, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, - MVLI.VarComponents, MapTypeModifier, MapType, - IsMapTypeImplicit, MapLoc); + MVLI.VarComponents, Modifiers, ModifiersLoc, + MapType, IsMapTypeImplicit, MapLoc); } QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 3f4b21eb556..50ecd6d81fc 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1796,14 +1796,16 @@ public: /// By default, performs semantic analysis to build the new OpenMP clause. /// Subclasses may override this routine to provide different behavior. OMPClause * - RebuildOMPMapClause(OpenMPMapClauseKind MapTypeModifier, + RebuildOMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, + ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPMapClause(MapTypeModifier, MapType, - IsMapTypeImplicit, MapLoc, ColonLoc, - VarList, StartLoc, LParenLoc, EndLoc); + return getSema().ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, + MapType, IsMapTypeImplicit, MapLoc, + ColonLoc, VarList, StartLoc, + LParenLoc, EndLoc); } /// Build a new OpenMP 'num_teams' clause. @@ -8803,9 +8805,9 @@ OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) { Vars.push_back(EVar.get()); } return getDerived().RebuildOMPMapClause( - C->getMapTypeModifier(), C->getMapType(), C->isImplicitMapType(), - C->getMapLoc(), C->getColonLoc(), Vars, C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); + C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), C->getMapType(), + C->isImplicitMapType(), C->getMapLoc(), C->getColonLoc(), Vars, + C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); } template <typename Derived> diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 558100d45c1..e0b2b24a0d3 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -12284,8 +12284,11 @@ void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) { void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { C->setLParenLoc(Record.readSourceLocation()); - C->setMapTypeModifier( - static_cast<OpenMPMapClauseKind>(Record.readInt())); + for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + C->setMapTypeModifier( + I, static_cast<OpenMPMapModifierKind>(Record.readInt())); + C->setMapTypeModifierLoc(I, Record.readSourceLocation()); + } C->setMapType( static_cast<OpenMPMapClauseKind>(Record.readInt())); C->setMapLoc(Record.readSourceLocation()); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 45de91f76fd..37adcb70640 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6782,7 +6782,10 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); - Record.push_back(C->getMapTypeModifier()); + for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + Record.push_back(C->getMapTypeModifier(I)); + Record.AddSourceLocation(C->getMapTypeModifierLoc(I)); + } Record.push_back(C->getMapType()); Record.AddSourceLocation(C->getMapLoc()); Record.AddSourceLocation(C->getColonLoc()); |