summaryrefslogtreecommitdiffstats
path: root/lib/Parse
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2019-02-19 16:38:20 +0000
committerMichael Kruse <llvm@meinersbur.de>2019-02-19 16:38:20 +0000
commit238a43704cfd30b68eb78775e123609faab5ca11 (patch)
tree5ab668141f5c0b3c0d05189cf19860322762250b /lib/Parse
parent283f308bdb5893bab1f36791711346e746045f94 (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.cpp83
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);
}