aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseOpenMP.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/Parse/ParseOpenMP.cpp
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
downloadsrc-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.tar.gz
src-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.zip
Notes
Diffstat (limited to 'lib/Parse/ParseOpenMP.cpp')
-rw-r--r--lib/Parse/ParseOpenMP.cpp390
1 files changed, 239 insertions, 151 deletions
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index a413e96a91e7..dd2a8aae9f2f 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -314,7 +314,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
ExprResult CombinerResult =
Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
- D->getLocation(), /*DiscardedValue=*/true);
+ D->getLocation(), /*DiscardedValue*/ false);
Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
@@ -353,12 +353,18 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
// Check if initializer is omp_priv <init_expr> or something else.
if (Tok.is(tok::identifier) &&
Tok.getIdentifierInfo()->isStr("omp_priv")) {
- ConsumeToken();
- ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
+ if (Actions.getLangOpts().CPlusPlus) {
+ InitializerResult = Actions.ActOnFinishFullExpr(
+ ParseAssignmentExpression().get(), D->getLocation(),
+ /*DiscardedValue*/ false);
+ } else {
+ ConsumeToken();
+ ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
+ }
} else {
InitializerResult = Actions.ActOnFinishFullExpr(
ParseAssignmentExpression().get(), D->getLocation(),
- /*DiscardedValue=*/true);
+ /*DiscardedValue*/ false);
}
Actions.ActOnOpenMPDeclareReductionInitializerEnd(
D, InitializerResult.get(), OmpPrivParm);
@@ -415,11 +421,22 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
ExprVector Exprs;
CommaLocsTy CommaLocs;
- if (ParseExpressionList(Exprs, CommaLocs, [this, OmpPrivParm, &Exprs] {
- Actions.CodeCompleteConstructor(
- getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
- OmpPrivParm->getLocation(), Exprs);
- })) {
+ SourceLocation LParLoc = T.getOpenLocation();
+ if (ParseExpressionList(
+ Exprs, CommaLocs, [this, OmpPrivParm, LParLoc, &Exprs] {
+ QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
+ getCurScope(),
+ OmpPrivParm->getType()->getCanonicalTypeInternal(),
+ OmpPrivParm->getLocation(), Exprs, LParLoc);
+ CalledSignatureHelp = true;
+ Actions.CodeCompleteExpression(getCurScope(), PreferredType);
+ })) {
+ if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
+ Actions.ProduceConstructorSignatureHelp(
+ getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
+ OmpPrivParm->getLocation(), Exprs, LParLoc);
+ CalledSignatureHelp = true;
+ }
Actions.ActOnInitializerError(OmpPrivParm);
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
} else {
@@ -478,7 +495,7 @@ public:
Sema &Actions = P.getActions();
// Allow 'this' within late-parsed attributes.
- ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, /*TypeQuals=*/0,
+ ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
ND && ND->isCXXInstanceMember());
// If the Decl is templatized, add template parameters to scope.
@@ -627,6 +644,60 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
LinModifiers, Steps, SourceRange(Loc, EndLoc));
}
+Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
+ // OpenMP 4.5 syntax with list of entities.
+ Sema::NamedDeclSetType SameDirectiveDecls;
+ while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
+ if (Tok.is(tok::identifier)) {
+ IdentifierInfo *II = Tok.getIdentifierInfo();
+ StringRef ClauseName = II->getName();
+ // Parse 'to|link' clauses.
+ if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT)) {
+ Diag(Tok, diag::err_omp_declare_target_unexpected_clause) << ClauseName;
+ break;
+ }
+ ConsumeToken();
+ }
+ auto &&Callback = [this, MT, &SameDirectiveDecls](
+ CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
+ Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
+ SameDirectiveDecls);
+ };
+ if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
+ /*AllowScopeSpecifier=*/true))
+ break;
+
+ // Consume optional ','.
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ }
+ SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+ ConsumeAnyToken();
+ SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
+ SameDirectiveDecls.end());
+ if (Decls.empty())
+ return DeclGroupPtrTy();
+ return Actions.BuildDeclaratorGroup(Decls);
+}
+
+void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
+ SourceLocation DTLoc) {
+ if (DKind != OMPD_end_declare_target) {
+ Diag(Tok, diag::err_expected_end_declare_target);
+ Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
+ return;
+ }
+ ConsumeAnyToken();
+ if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
+ << getOpenMPDirectiveName(OMPD_end_declare_target);
+ SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+ }
+ // Skip the last annot_pragma_openmp_end.
+ ConsumeAnyToken();
+}
+
/// Parsing of declarative OpenMP directives.
///
/// threadprivate-directive:
@@ -642,6 +713,10 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
/// annot_pragma_openmp_end
/// <function declaration/definition>
///
+/// requires directive:
+/// annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
+/// annot_pragma_openmp_end
+///
Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
DeclSpec::TST TagType, Decl *Tag) {
@@ -670,6 +745,46 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
}
break;
}
+ case OMPD_requires: {
+ SourceLocation StartLoc = ConsumeToken();
+ SmallVector<OMPClause *, 5> Clauses;
+ SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
+ FirstClauses(OMPC_unknown + 1);
+ if (Tok.is(tok::annot_pragma_openmp_end)) {
+ Diag(Tok, diag::err_omp_expected_clause)
+ << getOpenMPDirectiveName(OMPD_requires);
+ break;
+ }
+ while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ OpenMPClauseKind CKind = Tok.isAnnotation()
+ ? OMPC_unknown
+ : getOpenMPClauseKind(PP.getSpelling(Tok));
+ Actions.StartOpenMPClause(CKind);
+ OMPClause *Clause =
+ ParseOpenMPClause(OMPD_requires, CKind, !FirstClauses[CKind].getInt());
+ SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch);
+ FirstClauses[CKind].setInt(true);
+ if (Clause != nullptr)
+ Clauses.push_back(Clause);
+ if (Tok.is(tok::annot_pragma_openmp_end)) {
+ Actions.EndOpenMPClause();
+ break;
+ }
+ // Skip ',' if any.
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ Actions.EndOpenMPClause();
+ }
+ // Consume final annot_pragma_openmp_end
+ if (Clauses.size() == 0) {
+ Diag(Tok, diag::err_omp_expected_clause)
+ << getOpenMPDirectiveName(OMPD_requires);
+ ConsumeAnnotationToken();
+ return nullptr;
+ }
+ ConsumeAnnotationToken();
+ return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
+ }
case OMPD_declare_reduction:
ConsumeToken();
if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
@@ -724,43 +839,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
case OMPD_declare_target: {
SourceLocation DTLoc = ConsumeAnyToken();
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
- // OpenMP 4.5 syntax with list of entities.
- Sema::NamedDeclSetType SameDirectiveDecls;
- while (Tok.isNot(tok::annot_pragma_openmp_end)) {
- OMPDeclareTargetDeclAttr::MapTypeTy MT =
- OMPDeclareTargetDeclAttr::MT_To;
- if (Tok.is(tok::identifier)) {
- IdentifierInfo *II = Tok.getIdentifierInfo();
- StringRef ClauseName = II->getName();
- // Parse 'to|link' clauses.
- if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName,
- MT)) {
- Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
- << ClauseName;
- break;
- }
- ConsumeToken();
- }
- auto &&Callback = [this, MT, &SameDirectiveDecls](
- CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
- Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
- SameDirectiveDecls);
- };
- if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
- /*AllowScopeSpecifier=*/true))
- break;
-
- // Consume optional ','.
- if (Tok.is(tok::comma))
- ConsumeToken();
- }
- SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
- ConsumeAnyToken();
- SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
- SameDirectiveDecls.end());
- if (Decls.empty())
- return DeclGroupPtrTy();
- return Actions.BuildDeclaratorGroup(Decls);
+ return ParseOMPDeclareTargetClauses();
}
// Skip the last annot_pragma_openmp_end.
@@ -771,8 +850,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
llvm::SmallVector<Decl *, 4> Decls;
DKind = parseOpenMPDirectiveKind(*this);
- while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target &&
- Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) {
+ while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
+ Tok.isNot(tok::r_brace)) {
DeclGroupPtrTy Ptr;
// Here we expect to see some function declaration.
if (AS == AS_none) {
@@ -799,19 +878,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
}
}
- if (DKind == OMPD_end_declare_target) {
- ConsumeAnyToken();
- if (Tok.isNot(tok::annot_pragma_openmp_end)) {
- Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
- << getOpenMPDirectiveName(OMPD_end_declare_target);
- SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
- }
- // Skip the last annot_pragma_openmp_end.
- ConsumeAnyToken();
- } else {
- Diag(Tok, diag::err_expected_end_declare_target);
- Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
- }
+ ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
Actions.ActOnFinishOpenMPDeclareTargetDirective();
return Actions.BuildDeclaratorGroup(Decls);
}
@@ -1124,6 +1191,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
+ case OMPD_requires:
Diag(Tok, diag::err_omp_unexpected_directive)
<< 1 << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end);
@@ -1275,11 +1343,15 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
break;
case OMPC_default:
case OMPC_proc_bind:
+ case OMPC_atomic_default_mem_order:
// OpenMP [2.14.3.1, Restrictions]
// Only a single default clause may be specified on a parallel, task or
// teams directive.
// OpenMP [2.5, parallel Construct, Restrictions]
// At most one proc_bind clause can appear on the directive.
+ // OpenMP [5.0, Requires directive, Restrictions]
+ // At most one atomic_default_mem_order clause can appear
+ // on the directive
if (!FirstClause) {
Diag(Tok, diag::err_omp_more_one_clause)
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
@@ -1316,10 +1388,16 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_threads:
case OMPC_simd:
case OMPC_nogroup:
+ case OMPC_unified_address:
+ case OMPC_unified_shared_memory:
+ case OMPC_reverse_offload:
+ case OMPC_dynamic_allocators:
// OpenMP [2.7.1, Restrictions, p. 9]
// Only one ordered clause can appear on a loop directive.
// OpenMP [2.7.1, Restrictions, C/C++, p. 4]
// Only one nowait clause can appear on a for directive.
+ // OpenMP [5.0, Requires directive, Restrictions]
+ // Each of the requires clauses can appear at most once on the directive.
if (!FirstClause) {
Diag(Tok, diag::err_omp_more_one_clause)
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
@@ -1377,7 +1455,7 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
ExprResult LHS(ParseCastExpression(
/*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
- Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
+ Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
// Parse ')'.
RLoc = Tok.getLocation();
@@ -1633,7 +1711,8 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
SourceLocation ELoc = Tok.getLocation();
ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
- Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
+ Val =
+ Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
}
// Parse ')'.
@@ -1696,6 +1775,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,
@@ -1703,7 +1855,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
OpenMPVarListDataTy &Data) {
UnqualifiedId UnqualifiedReductionId;
bool InvalidReductionId = false;
- bool MapTypeModifierSpecified = false;
// Parse '('.
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
@@ -1775,104 +1926,40 @@ 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();
- bool ColonExpected = false;
-
- 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;
- } else {
- MapTypeModifierSpecified = true;
- }
-
- 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;
- } else {
- MapTypeModifierSpecified = true;
- }
- 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;
}
if (Tok.is(tok::colon))
Data.ColonLoc = ConsumeToken();
- else if (ColonExpected)
- Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
}
bool IsComma =
(Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
(Kind == OMPC_reduction && !InvalidReductionId) ||
- (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown &&
- (!MapTypeModifierSpecified ||
- Data.MapTypeModifier == OMPC_MAP_always)) ||
+ (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown) ||
(Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
@@ -1910,7 +1997,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
Data.ColonLoc = Tok.getLocation();
SourceLocation ELoc = ConsumeToken();
ExprResult Tail = ParseAssignmentExpression();
- Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
+ Tail =
+ Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
if (Tail.isUsable())
Data.TailExpr = Tail.get();
else
@@ -1957,7 +2045,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 ')'
@@ -1988,7 +2076,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);
}