OpenMPMapClauseKind MapTypeModifier;
/// \brief Map type for the 'map' clause.
OpenMPMapClauseKind MapType;
+ /// \brief Is this an implicit map type or not.
+ bool MapTypeIsImplicit;
/// \brief Location of the map type.
SourceLocation MapLoc;
/// \brief Colon location.
///
/// \param MapTypeModifier Map type modifier.
/// \param MapType Map type.
+ /// \param MapTypeIsImplicit Map type is inferred implicitly.
/// \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.
///
explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier,
- OpenMPMapClauseKind MapType, SourceLocation MapLoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPMapClause>(OMPC_map, StartLoc, LParenLoc, EndLoc, N),
- MapTypeModifier(MapTypeModifier), MapType(MapType), MapLoc(MapLoc) {}
+ OpenMPMapClauseKind MapType, bool MapTypeIsImplicit,
+ SourceLocation MapLoc, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ unsigned N)
+ : OMPVarListClause<OMPMapClause>(OMPC_map, StartLoc, LParenLoc, EndLoc,
+ N),
+ MapTypeModifier(MapTypeModifier), MapType(MapType),
+ MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {}
/// \brief Build an empty clause.
///
explicit OMPMapClause(unsigned N)
: OMPVarListClause<OMPMapClause>(OMPC_map, SourceLocation(),
SourceLocation(), SourceLocation(), N),
- MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), MapLoc() {}
+ MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown),
+ MapTypeIsImplicit(false), MapLoc() {}
public:
/// \brief Creates clause with a list of variables \a VL.
/// \param VL List of references to the variables.
/// \param TypeModifier Map type modifier.
/// \param Type Map type.
+ /// \param TypeIsImplicit Map type is inferred implicitly.
/// \param TypeLoc Location of the map type.
///
static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL,
OpenMPMapClauseKind TypeModifier,
- OpenMPMapClauseKind Type, SourceLocation TypeLoc);
+ OpenMPMapClauseKind Type, bool TypeIsImplicit,
+ SourceLocation TypeLoc);
/// \brief Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \brief Fetches mapping kind for the clause.
OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; }
+ /// \brief Is this an implicit map type?
+ /// We have to capture 'IsMapTypeImplicit' from the parser for more
+ /// informative error messages. It helps distinguish map(r) from
+ /// map(tofrom: r), which is important to print more helpful error
+ /// messages for some target directives.
+ bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; }
+
/// \brief Fetches the map type modifier for the clause.
OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY {
return MapTypeModifier;
CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
- OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc);
+ OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
+ SourceLocation DepLinMapLoc);
/// \brief Called on well-formed 'private' clause.
OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// \brief Called on well-formed 'map' clause.
- OMPClause *ActOnOpenMPMapClause(
- OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType,
- SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
- SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
+ OMPClause *
+ ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
+ OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
+ SourceLocation MapLoc, SourceLocation ColonLoc,
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc);
/// \brief Called on well-formed 'num_teams' clause.
OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, 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, TypeLoc, StartLoc, LParenLoc, EndLoc, VL.size());
+ OMPMapClause *Clause =
+ new (Mem) OMPMapClause(TypeModifier, Type, TypeIsImplicit, TypeLoc,
+ StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
Clause->setMapTypeModifier(TypeModifier);
Clause->setMapType(Type);
OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val;
OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
+ bool MapTypeIsImplicit = false;
bool MapTypeModifierSpecified = false;
bool UnexpectedId = false;
SourceLocation DepLinMapLoc;
Kind, llvm::None, /*TailExpr=*/nullptr, Loc, LOpen,
/*ColonLoc=*/SourceLocation(), Tok.getLocation(),
ReductionIdScopeSpec, DeclarationNameInfo(), DepKind,
- LinearModifier, MapTypeModifier, MapType, DepLinMapLoc);
+ LinearModifier, MapTypeModifier, MapType, MapTypeIsImplicit,
+ DepLinMapLoc);
}
}
if (Tok.is(tok::colon)) {
ConsumeToken();
} else {
MapType = OMPC_MAP_tofrom;
+ MapTypeIsImplicit = true;
}
} else {
MapType = OMPC_MAP_tofrom;
+ MapTypeIsImplicit = true;
}
} else {
UnexpectedId = true;
ReductionIdScopeSpec,
ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
: DeclarationNameInfo(),
- DepKind, LinearModifier, MapTypeModifier, MapType, DepLinMapLoc);
+ DepKind, LinearModifier, MapTypeModifier, MapType, MapTypeIsImplicit,
+ DepLinMapLoc);
}
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
- OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
- OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc) {
+ OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
+ OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
+ SourceLocation DepLinMapLoc) {
OMPClause *Res = nullptr;
switch (Kind) {
case OMPC_private:
StartLoc, LParenLoc, EndLoc);
break;
case OMPC_map:
- Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, DepLinMapLoc, ColonLoc,
- VarList, StartLoc, LParenLoc, EndLoc);
+ Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
+ DepLinMapLoc, ColonLoc, VarList, StartLoc,
+ LParenLoc, EndLoc);
break;
case OMPC_if:
case OMPC_final:
return true;
}
-OMPClause *Sema::ActOnOpenMPMapClause(
- OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType,
- SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
- SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
+OMPClause *
+Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
+ OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
+ SourceLocation MapLoc, SourceLocation ColonLoc,
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc) {
SmallVector<Expr *, 4> Vars;
for (auto &RE : VarList) {
if (DKind == OMPD_target_enter_data &&
!(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
- <<
- // TODO: Need to determine if map type is implicitly determined
- 0 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
+ << (IsMapTypeImplicit ? 1 : 0)
+ << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
<< getOpenMPDirectiveName(DKind);
// Proceed to add the variable in a map clause anyway, to prevent
// further spurious messages
!(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
MapType == OMPC_MAP_delete)) {
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
- <<
- // TODO: Need to determine if map type is implicitly determined
- 0 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
+ << (IsMapTypeImplicit ? 1 : 0)
+ << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
<< getOpenMPDirectiveName(DKind);
// Proceed to add the variable in a map clause anyway, to prevent
// further spurious messages
return nullptr;
return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
- MapTypeModifier, MapType, MapLoc);
+ MapTypeModifier, MapType, IsMapTypeImplicit,
+ MapLoc);
}
OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
///
/// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
- OMPClause *RebuildOMPMapClause(
- OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType,
- SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc) {
- return getSema().ActOnOpenMPMapClause(MapTypeModifier, MapType, MapLoc,
- ColonLoc, VarList,StartLoc,
- LParenLoc, EndLoc);
+ OMPClause *
+ RebuildOMPMapClause(OpenMPMapClauseKind MapTypeModifier,
+ 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);
}
/// \brief Build a new OpenMP 'num_teams' clause.
Vars.push_back(EVar.get());
}
return getDerived().RebuildOMPMapClause(
- C->getMapTypeModifier(), C->getMapType(), C->getMapLoc(),
- C->getColonLoc(), Vars, C->getLocStart(), C->getLParenLoc(),
- C->getLocEnd());
+ C->getMapTypeModifier(), C->getMapType(), C->isImplicitMapType(),
+ C->getMapLoc(), C->getColonLoc(), Vars, C->getLocStart(),
+ C->getLParenLoc(), C->getLocEnd());
}
template <typename Derived>
int r;
#pragma omp target enter data // expected-error {{expected at least one map clause for '#pragma omp target enter data'}}
+ #pragma omp target enter data map(r) // expected-error {{map type must be specified for '#pragma omp target enter data'}}
#pragma omp target enter data map(tofrom: r) // expected-error {{map type 'tofrom' is not allowed for '#pragma omp target enter data'}}
#pragma omp target enter data map(always, to: r)
int r;
#pragma omp target exit data // expected-error {{expected at least one map clause for '#pragma omp target exit data'}}
+ #pragma omp target exit data map(r) // expected-error {{map type must be specified for '#pragma omp target exit data'}}
#pragma omp target exit data map(tofrom: r) // expected-error {{map type 'tofrom' is not allowed for '#pragma omp target exit data'}}
#pragma omp target exit data map(always, from: r)