diff options
author | Michael Kruse <llvm@meinersbur.de> | 2019-02-19 16:38:20 +0000 |
---|---|---|
committer | Michael Kruse <llvm@meinersbur.de> | 2019-02-19 16:38:20 +0000 |
commit | 238a43704cfd30b68eb78775e123609faab5ca11 (patch) | |
tree | 5ab668141f5c0b3c0d05189cf19860322762250b /lib/Parse | |
parent | 283f308bdb5893bab1f36791711346e746045f94 (diff) |
[OpenMP 5.0] Parsing/sema support for map clause with mapper modifier.
This patch implements the parsing and sema support for OpenMP map
clauses with potential user-defined mapper attached. User defined mapper
is a new feature in OpenMP 5.0. A map clause can have an explicit or
implicit associated mapper, which instructs the compiler to generate
extra data mapping. An example is shown below:
struct S { int len; int *d; };
#pragma omp declare mapper(id: struct S s) map(s, s.d[0:s.len])
struct S ss;
#pragma omp target map(mapper(id) tofrom: ss) // use the mapper with name 'id' to map ss
Contributed-by: Lingda Li <lildmh@gmail.com>
Differential Revision: https://reviews.llvm.org/D58074
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354347 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/ParseOpenMP.cpp | 83 |
1 files changed, 57 insertions, 26 deletions
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index d0463416f5..fafc34c960 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -1961,36 +1961,62 @@ static OpenMPMapModifierKind isMapModifier(Parser &P) { /// 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); +/// where, map-type-modifier ::= always | close | mapper(mapper-identifier) +bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) { + while (getCurToken().isNot(tok::colon)) { + OpenMPMapModifierKind TypeModifier = isMapModifier(*this); if (TypeModifier == OMPC_MAP_MODIFIER_always || TypeModifier == OMPC_MAP_MODIFIER_close) { Data.MapTypeModifiers.push_back(TypeModifier); Data.MapTypeModifiersLoc.push_back(Tok.getLocation()); - P.ConsumeToken(); + ConsumeToken(); + } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) { + Data.MapTypeModifiers.push_back(TypeModifier); + Data.MapTypeModifiersLoc.push_back(Tok.getLocation()); + ConsumeToken(); + // Parse '('. + BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon); + if (T.expectAndConsume(diag::err_expected_lparen_after, + getOpenMPSimpleClauseTypeName( + OMPC_map, OMPC_MAP_MODIFIER_mapper))) { + SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch); + return true; + } + // Parse mapper-identifier + if (getLangOpts().CPlusPlus) + ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, + /*ObjectType=*/nullptr, + /*EnteringContext=*/false); + if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) { + Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier); + SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch); + return true; + } + auto &DeclNames = Actions.getASTContext().DeclarationNames; + Data.ReductionOrMapperId = DeclarationNameInfo( + DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation()); + ConsumeToken(); + // Parse ')'. + T.consumeClose(); } 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(); + Diag(Tok, diag::err_omp_map_type_modifier_missing); + 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(); + return false; + Diag(Tok, diag::err_omp_unknown_map_type_modifier); + ConsumeToken(); } - if (P.getCurToken().is(tok::comma)) - P.ConsumeToken(); + if (getCurToken().is(tok::comma)) + ConsumeToken(); } + return false; } /// Checks if the token is a valid map-type. @@ -2027,6 +2053,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPVarListDataTy &Data) { UnqualifiedId UnqualifiedReductionId; bool InvalidReductionId = false; + bool IsInvalidMapModifier = false; // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); @@ -2042,11 +2069,11 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Kind == OMPC_in_reduction) { ColonProtectionRAIIObject ColonRAII(*this); if (getLangOpts().CPlusPlus) - ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec, + ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, /*ObjectType=*/nullptr, /*EnteringContext=*/false); - InvalidReductionId = ParseReductionId(*this, Data.ReductionIdScopeSpec, - UnqualifiedReductionId); + InvalidReductionId = ParseReductionId( + *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId); if (InvalidReductionId) { SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); @@ -2056,7 +2083,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, else Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier"; if (!InvalidReductionId) - Data.ReductionId = + Data.ReductionOrMapperId = Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId); } else if (Kind == OMPC_depend) { // Handle dependency type for depend clause. @@ -2115,8 +2142,9 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, // 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); + IsInvalidMapModifier = parseMapTypeModifiers(Data); + if (!IsInvalidMapModifier) + parseMapType(*this, Data); } if (Data.MapType == OMPC_MAP_unknown) { Data.MapType = OMPC_MAP_tofrom; @@ -2185,7 +2213,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown && Vars.empty()) || (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) || - (MustHaveTail && !Data.TailExpr) || InvalidReductionId; + (MustHaveTail && !Data.TailExpr) || InvalidReductionId || + IsInvalidMapModifier; } /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate', @@ -2218,6 +2247,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /// 'depend' '(' in | out | inout : list | source ')' /// map-clause: /// 'map' '(' [ [ always [,] ] [ close [,] ] +/// [ mapper(mapper-identifier) [,] ] /// to | from | tofrom | alloc | release | delete ':' ] list ')'; /// to-clause: /// 'to' '(' list ')' @@ -2245,10 +2275,11 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, if (ParseOnly) return nullptr; + OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc); return Actions.ActOnOpenMPVarListClause( - Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Data.RLoc, - Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind, - Data.MapTypeModifiers, Data.MapTypeModifiersLoc, Data.MapType, - Data.IsMapTypeImplicit, Data.DepLinMapLoc); + Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc, + Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind, + Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc, + Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc); } |