[OpenMP] Parsing and sema support for the to clause
Summary: The patch contains the parsing and sema support for the `to` clause. Patch based on the original post by Kelvin Li. Reviewers: carlo.bertolli, hfinkel, kkwli0, arpith-jacob, ABataev Subscribers: caomhin, cfe-commits Differential Revision: http://reviews.llvm.org/D18597 llvm-svn: 270880
This commit is contained in:
parent
7f32420ed5
commit
661c0904e1
|
@ -4010,6 +4010,109 @@ public:
|
|||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief This represents clause 'to' in the '#pragma omp ...'
|
||||
/// directives.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp target update to(a,b)
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp target update' has clause 'to'
|
||||
/// with the variables 'a' and 'b'.
|
||||
///
|
||||
class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
|
||||
private llvm::TrailingObjects<
|
||||
OMPToClause, Expr *, ValueDecl *, unsigned,
|
||||
OMPClauseMappableExprCommon::MappableComponent> {
|
||||
friend TrailingObjects;
|
||||
friend OMPVarListClause;
|
||||
friend OMPMappableExprListClause;
|
||||
friend class OMPClauseReader;
|
||||
|
||||
/// Define the sizes of each trailing object array except the last one. This
|
||||
/// is required for TrailingObjects to work properly.
|
||||
size_t numTrailingObjects(OverloadToken<Expr *>) const {
|
||||
return varlist_size();
|
||||
}
|
||||
size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
|
||||
return getUniqueDeclarationsNum();
|
||||
}
|
||||
size_t numTrailingObjects(OverloadToken<unsigned>) const {
|
||||
return getUniqueDeclarationsNum() + getTotalComponentListNum();
|
||||
}
|
||||
|
||||
/// \brief Build clause with number of variables \a NumVars.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
/// \param NumVars Number of expressions listed in this clause.
|
||||
/// \param NumUniqueDeclarations Number of unique base declarations in this
|
||||
/// clause.
|
||||
/// \param NumComponentLists Number of component lists in this clause.
|
||||
/// \param NumComponents Total number of expression components in the clause.
|
||||
///
|
||||
explicit OMPToClause(SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc, unsigned NumVars,
|
||||
unsigned NumUniqueDeclarations,
|
||||
unsigned NumComponentLists, unsigned NumComponents)
|
||||
: OMPMappableExprListClause(OMPC_to, StartLoc, LParenLoc, EndLoc, NumVars,
|
||||
NumUniqueDeclarations, NumComponentLists,
|
||||
NumComponents) {}
|
||||
|
||||
/// \brief Build an empty clause.
|
||||
///
|
||||
/// \param NumVars Number of expressions listed in this clause.
|
||||
/// \param NumUniqueDeclarations Number of unique base declarations in this
|
||||
/// clause.
|
||||
/// \param NumComponentLists Number of component lists in this clause.
|
||||
/// \param NumComponents Total number of expression components in the clause.
|
||||
///
|
||||
explicit OMPToClause(unsigned NumVars, unsigned NumUniqueDeclarations,
|
||||
unsigned NumComponentLists, unsigned NumComponents)
|
||||
: OMPMappableExprListClause(
|
||||
OMPC_to, SourceLocation(), SourceLocation(), SourceLocation(),
|
||||
NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
|
||||
|
||||
public:
|
||||
/// \brief Creates clause with a list of variables \a Vars.
|
||||
///
|
||||
/// \param C AST context.
|
||||
/// \brief StartLoc Starting location of the clause.
|
||||
/// \brief EndLoc Ending location of the clause.
|
||||
/// \param Vars The original expression used in the clause.
|
||||
/// \param Declarations Declarations used in the clause.
|
||||
/// \param ComponentLists Component lists used in the clause.
|
||||
///
|
||||
static OMPToClause *Create(const ASTContext &C, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation EndLoc,
|
||||
ArrayRef<Expr *> Vars,
|
||||
ArrayRef<ValueDecl *> Declarations,
|
||||
MappableExprComponentListsRef ComponentLists);
|
||||
|
||||
/// \brief Creates an empty clause with the place for \a NumVars variables.
|
||||
///
|
||||
/// \param C AST context.
|
||||
/// \param NumVars Number of expressions listed in the clause.
|
||||
/// \param NumUniqueDeclarations Number of unique base declarations in this
|
||||
/// clause.
|
||||
/// \param NumComponentLists Number of unique base declarations in this
|
||||
/// clause.
|
||||
/// \param NumComponents Total number of expression components in the clause.
|
||||
///
|
||||
static OMPToClause *CreateEmpty(const ASTContext &C, unsigned NumVars,
|
||||
unsigned NumUniqueDeclarations,
|
||||
unsigned NumComponentLists,
|
||||
unsigned NumComponents);
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_to;
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
|
||||
reinterpret_cast<Stmt **>(varlist_end()));
|
||||
}
|
||||
};
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
|
||||
|
|
|
@ -2884,6 +2884,12 @@ RecursiveASTVisitor<Derived>::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPToClause(OMPToClause *C) {
|
||||
TRY_TO(VisitOMPClauseList(C));
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: look at the following tricky-seeming exprs to see if we
|
||||
// need to recurse on anything. These are ones that have methods
|
||||
// returning decls or qualtypes or nestednamespecifier -- though I'm
|
||||
|
|
|
@ -7934,8 +7934,8 @@ def err_omp_expected_var_name_member_expr_or_array_item : Error<
|
|||
"expected variable name%select{|, data member of current class}0, array element or array section">;
|
||||
def err_omp_expected_named_var_member_or_array_expression: Error<
|
||||
"expected expression containing only member accesses and/or array sections based on named variables">;
|
||||
def err_omp_bit_fields_forbidden_in_map_clause : Error<
|
||||
"bit fields cannot be used to specify storage in a map clause">;
|
||||
def err_omp_bit_fields_forbidden_in_clause : Error<
|
||||
"bit fields cannot be used to specify storage in a '%0' clause">;
|
||||
def err_array_section_does_not_specify_contiguous_storage : Error<
|
||||
"array section does not specify contiguous storage">;
|
||||
def err_omp_union_type_not_allowed : Error<
|
||||
|
@ -8076,6 +8076,8 @@ def err_omp_clause_floating_type_arg : Error<
|
|||
"arguments of OpenMP clause 'reduction' with bitwise operators cannot be of floating type">;
|
||||
def err_omp_once_referenced : Error<
|
||||
"variable can appear only once in OpenMP '%0' clause">;
|
||||
def err_omp_once_referenced_in_target_update : Error<
|
||||
"variable can appear only once in OpenMP 'target update' construct">;
|
||||
def note_omp_referenced : Note<
|
||||
"previously referenced here">;
|
||||
def err_omp_reduction_in_task : Error<
|
||||
|
@ -8213,8 +8215,8 @@ def note_omp_polymorphic_in_target : Note<
|
|||
"mappable type cannot be polymorphic">;
|
||||
def note_omp_static_member_in_target : Note<
|
||||
"mappable type cannot contain static members">;
|
||||
def err_omp_threadprivate_in_map : Error<
|
||||
"threadprivate variables are not allowed in map clause">;
|
||||
def err_omp_threadprivate_in_clause : Error<
|
||||
"threadprivate variables are not allowed in '%0' clause">;
|
||||
def err_omp_wrong_ordered_loop_count : Error<
|
||||
"the parameter of the 'ordered' clause must be greater than or equal to the parameter of the 'collapse' clause">;
|
||||
def note_collapse_loop_count : Note<
|
||||
|
|
|
@ -210,6 +210,7 @@ OPENMP_CLAUSE(num_tasks, OMPNumTasksClause)
|
|||
OPENMP_CLAUSE(hint, OMPHintClause)
|
||||
OPENMP_CLAUSE(dist_schedule, OMPDistScheduleClause)
|
||||
OPENMP_CLAUSE(defaultmap, OMPDefaultmapClause)
|
||||
OPENMP_CLAUSE(to, OMPToClause)
|
||||
|
||||
// Clauses allowed for OpenMP directive 'parallel'.
|
||||
OPENMP_PARALLEL_CLAUSE(if)
|
||||
|
@ -450,6 +451,7 @@ OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear)
|
|||
// TODO More clauses for 'target update' directive.
|
||||
OPENMP_TARGET_UPDATE_CLAUSE(if)
|
||||
OPENMP_TARGET_UPDATE_CLAUSE(device)
|
||||
OPENMP_TARGET_UPDATE_CLAUSE(to)
|
||||
|
||||
// Clauses allowed for OpenMP directive 'teams'.
|
||||
// TODO More clauses for 'teams' directive.
|
||||
|
|
|
@ -8418,6 +8418,11 @@ public:
|
|||
OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
|
||||
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
|
||||
SourceLocation KindLoc, SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed 'to' clause.
|
||||
OMPClause *ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc);
|
||||
|
||||
/// \brief The kind of conversion being performed.
|
||||
enum CheckedConversionKind {
|
||||
|
|
|
@ -87,6 +87,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
|
|||
case OMPC_defaultmap:
|
||||
case OMPC_unknown:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -148,6 +149,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
|
|||
case OMPC_defaultmap:
|
||||
case OMPC_unknown:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -625,3 +627,52 @@ OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned NumVars,
|
|||
return new (Mem) OMPMapClause(NumVars, NumUniqueDeclarations,
|
||||
NumComponentLists, NumComponents);
|
||||
}
|
||||
|
||||
OMPToClause *OMPToClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc, ArrayRef<Expr *> Vars,
|
||||
ArrayRef<ValueDecl *> Declarations,
|
||||
MappableExprComponentListsRef ComponentLists) {
|
||||
unsigned NumVars = Vars.size();
|
||||
unsigned NumUniqueDeclarations =
|
||||
getUniqueDeclarationsTotalNumber(Declarations);
|
||||
unsigned NumComponentLists = ComponentLists.size();
|
||||
unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
|
||||
|
||||
// We need to allocate:
|
||||
// NumVars x Expr* - we have an original list expression for each clause list
|
||||
// entry.
|
||||
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
|
||||
// with each component list.
|
||||
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
|
||||
// number of lists for each unique declaration and the size of each component
|
||||
// list.
|
||||
// NumComponents x MappableComponent - the total of all the components in all
|
||||
// the lists.
|
||||
void *Mem = C.Allocate(
|
||||
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
||||
OMPClauseMappableExprCommon::MappableComponent>(
|
||||
NumVars, NumUniqueDeclarations,
|
||||
NumUniqueDeclarations + NumComponentLists, NumComponents));
|
||||
|
||||
OMPToClause *Clause = new (Mem)
|
||||
OMPToClause(StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,
|
||||
NumComponentLists, NumComponents);
|
||||
|
||||
Clause->setVarRefs(Vars);
|
||||
Clause->setClauseInfo(Declarations, ComponentLists);
|
||||
return Clause;
|
||||
}
|
||||
|
||||
OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C, unsigned NumVars,
|
||||
unsigned NumUniqueDeclarations,
|
||||
unsigned NumComponentLists,
|
||||
unsigned NumComponents) {
|
||||
void *Mem = C.Allocate(
|
||||
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
||||
OMPClauseMappableExprCommon::MappableComponent>(
|
||||
NumVars, NumUniqueDeclarations,
|
||||
NumUniqueDeclarations + NumComponentLists, NumComponents));
|
||||
return new (Mem) OMPToClause(NumVars, NumUniqueDeclarations,
|
||||
NumComponentLists, NumComponents);
|
||||
}
|
||||
|
|
|
@ -912,6 +912,14 @@ void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
|
|||
}
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
|
||||
if (!Node->varlist_empty()) {
|
||||
OS << "to";
|
||||
VisitOMPClauseList(Node, '(');
|
||||
OS << ")";
|
||||
}
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
|
||||
OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
|
||||
OMPC_dist_schedule, Node->getDistScheduleKind());
|
||||
|
|
|
@ -491,6 +491,9 @@ void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
|
|||
void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause *C) {
|
||||
Profiler->VisitStmt(C->getHint());
|
||||
}
|
||||
void OMPClauseProfiler::VisitOMPToClause(const OMPToClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -162,6 +162,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
|
|||
case OMPC_num_tasks:
|
||||
case OMPC_hint:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP simple clause kind");
|
||||
|
@ -297,6 +298,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
|||
case OMPC_num_tasks:
|
||||
case OMPC_hint:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP simple clause kind");
|
||||
|
|
|
@ -3134,6 +3134,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
|
|||
case OMPC_dist_schedule:
|
||||
case OMPC_defaultmap:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1043,7 +1043,7 @@ bool Parser::ParseOpenMPSimpleVarList(
|
|||
/// update-clause | capture-clause | seq_cst-clause | device-clause |
|
||||
/// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
|
||||
/// thread_limit-clause | priority-clause | grainsize-clause |
|
||||
/// nogroup-clause | num_tasks-clause | hint-clause
|
||||
/// nogroup-clause | num_tasks-clause | hint-clause | to-clause
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
||||
OpenMPClauseKind CKind, bool FirstClause) {
|
||||
|
@ -1167,6 +1167,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
case OMPC_flush:
|
||||
case OMPC_depend:
|
||||
case OMPC_map:
|
||||
case OMPC_to:
|
||||
Clause = ParseOpenMPVarListClause(DKind, CKind);
|
||||
break;
|
||||
case OMPC_unknown:
|
||||
|
@ -1727,6 +1728,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
|||
/// map-clause:
|
||||
/// 'map' '(' [ [ always , ]
|
||||
/// to | from | tofrom | alloc | release | delete ':' ] list ')';
|
||||
/// to-clause:
|
||||
/// 'to' '(' list ')'
|
||||
///
|
||||
/// For 'linear' clause linear-list may have the following forms:
|
||||
/// list
|
||||
|
|
|
@ -6521,10 +6521,11 @@ Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
|
|||
StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
// TODO: Set this flag accordingly when we add support for the 'to' and 'from'
|
||||
// clauses.
|
||||
bool seenMotionClause = false;
|
||||
|
||||
for (auto *C : Clauses) {
|
||||
if (C->getClauseKind() == OMPC_to)
|
||||
seenMotionClause = true;
|
||||
}
|
||||
if (!seenMotionClause) {
|
||||
Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
|
||||
return StmtError();
|
||||
|
@ -6798,6 +6799,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
|||
case OMPC_defaultmap:
|
||||
case OMPC_unknown:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
llvm_unreachable("Clause is not allowed.");
|
||||
}
|
||||
return Res;
|
||||
|
@ -7084,6 +7086,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
|
|||
case OMPC_defaultmap:
|
||||
case OMPC_unknown:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
llvm_unreachable("Clause is not allowed.");
|
||||
}
|
||||
return Res;
|
||||
|
@ -7235,6 +7238,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
|
|||
case OMPC_hint:
|
||||
case OMPC_unknown:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
llvm_unreachable("Clause is not allowed.");
|
||||
}
|
||||
return Res;
|
||||
|
@ -7419,6 +7423,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
|
|||
case OMPC_defaultmap:
|
||||
case OMPC_unknown:
|
||||
case OMPC_uniform:
|
||||
case OMPC_to:
|
||||
llvm_unreachable("Clause is not allowed.");
|
||||
}
|
||||
return Res;
|
||||
|
@ -7532,6 +7537,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
|
|||
DepLinMapLoc, ColonLoc, VarList, StartLoc,
|
||||
LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_to:
|
||||
Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_if:
|
||||
case OMPC_final:
|
||||
case OMPC_num_threads:
|
||||
|
@ -9874,13 +9882,14 @@ static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
|
|||
return ConstLength.getSExtValue() != 1;
|
||||
}
|
||||
|
||||
// Return the expression of the base of the map clause or null if it cannot
|
||||
// be determined and do all the necessary checks to see if the expression is
|
||||
// valid as a standalone map clause expression. In the process, record all the
|
||||
// Return the expression of the base of the mappable expression or null if it
|
||||
// cannot be determined and do all the necessary checks to see if the expression
|
||||
// is valid as a standalone mappable expression. In the process, record all the
|
||||
// components of the expression.
|
||||
static Expr *CheckMapClauseExpressionBase(
|
||||
Sema &SemaRef, Expr *E,
|
||||
OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents) {
|
||||
OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
|
||||
OpenMPClauseKind CKind) {
|
||||
SourceLocation ELoc = E->getExprLoc();
|
||||
SourceRange ERange = E->getSourceRange();
|
||||
|
||||
|
@ -9966,8 +9975,8 @@ static Expr *CheckMapClauseExpressionBase(
|
|||
// A bit-field cannot appear in a map clause.
|
||||
//
|
||||
if (FD->isBitField()) {
|
||||
SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_map_clause)
|
||||
<< CurE->getSourceRange();
|
||||
SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
|
||||
<< CurE->getSourceRange() << getOpenMPClauseName(CKind);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -10089,7 +10098,8 @@ static Expr *CheckMapClauseExpressionBase(
|
|||
static bool CheckMapConflicts(
|
||||
Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E,
|
||||
bool CurrentRegionOnly,
|
||||
OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents) {
|
||||
OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
|
||||
OpenMPClauseKind CKind) {
|
||||
assert(VD && E);
|
||||
SourceLocation ELoc = E->getExprLoc();
|
||||
SourceRange ERange = E->getSourceRange();
|
||||
|
@ -10164,7 +10174,13 @@ static bool CheckMapConflicts(
|
|||
// other, it means they are sharing storage.
|
||||
if (CI == CE && SI == SE) {
|
||||
if (CurrentRegionOnly) {
|
||||
if (CKind == OMPC_map)
|
||||
SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
|
||||
else {
|
||||
assert(CKind == OMPC_to);
|
||||
SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
|
||||
<< ERange;
|
||||
}
|
||||
SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
|
||||
<< RE->getSourceRange();
|
||||
return true;
|
||||
|
@ -10219,7 +10235,13 @@ static bool CheckMapConflicts(
|
|||
//
|
||||
// An expression is a subset of the other.
|
||||
if (CurrentRegionOnly && (CI == CE || SI == SE)) {
|
||||
if (CKind == OMPC_map)
|
||||
SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
|
||||
else {
|
||||
assert(CKind == OMPC_to);
|
||||
SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
|
||||
<< ERange;
|
||||
}
|
||||
SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
|
||||
<< RE->getSourceRange();
|
||||
return true;
|
||||
|
@ -10264,32 +10286,51 @@ static bool CheckMapConflicts(
|
|||
return FoundError;
|
||||
}
|
||||
|
||||
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;
|
||||
namespace {
|
||||
// Utility struct that gathers all the related lists associated with a mappable
|
||||
// expression.
|
||||
struct MappableVarListInfo final {
|
||||
// The list of expressions.
|
||||
ArrayRef<Expr *> VarList;
|
||||
// The list of processed expressions.
|
||||
SmallVector<Expr *, 16> ProcessedVarList;
|
||||
// The mappble components for each expression.
|
||||
OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
|
||||
// The base declaration of the variable.
|
||||
SmallVector<ValueDecl *, 16> VarBaseDeclarations;
|
||||
|
||||
MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
|
||||
// We have a list of components and base declarations for each entry in the
|
||||
// variable list.
|
||||
VarComponents.reserve(VarList.size());
|
||||
VarBaseDeclarations.reserve(VarList.size());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Check the validity of the provided variable list for the provided clause kind
|
||||
// \a CKind. In the check process the valid expressions, and mappable expression
|
||||
// components and variables are extracted and used to fill \a Vars,
|
||||
// \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
|
||||
// \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
|
||||
static void
|
||||
checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
|
||||
OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
|
||||
SourceLocation StartLoc,
|
||||
OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
|
||||
bool IsMapTypeImplicit = false) {
|
||||
// We only expect mappable expressions in 'to' and 'map' clauses.
|
||||
assert((CKind == OMPC_map || CKind == OMPC_to) &&
|
||||
"Unexpected clause kind with mappable expressions!");
|
||||
|
||||
// Keep track of the mappable components and base declarations in this clause.
|
||||
// Each entry in the list is going to have a list of components associated. We
|
||||
// record each set of the components so that we can build the clause later on.
|
||||
// In the end we should have the same amount of declarations and component
|
||||
// lists.
|
||||
OMPClauseMappableExprCommon::MappableExprComponentLists ClauseComponents;
|
||||
SmallVector<ValueDecl *, 16> ClauseBaseDeclarations;
|
||||
|
||||
ClauseComponents.reserve(VarList.size());
|
||||
ClauseBaseDeclarations.reserve(VarList.size());
|
||||
|
||||
for (auto &RE : VarList) {
|
||||
assert(RE && "Null expr in omp map");
|
||||
if (isa<DependentScopeDeclRefExpr>(RE)) {
|
||||
// It will be analyzed later.
|
||||
Vars.push_back(RE);
|
||||
continue;
|
||||
}
|
||||
for (auto &RE : MVLI.VarList) {
|
||||
assert(RE && "Null expr in omp to/map clause");
|
||||
SourceLocation ELoc = RE->getExprLoc();
|
||||
|
||||
auto *VE = RE->IgnoreParenLValueCasts();
|
||||
|
@ -10299,14 +10340,15 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
|
|||
VE->containsUnexpandedParameterPack()) {
|
||||
// We can only analyze this information once the missing information is
|
||||
// resolved.
|
||||
Vars.push_back(RE);
|
||||
MVLI.ProcessedVarList.push_back(RE);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto *SimpleExpr = RE->IgnoreParenCasts();
|
||||
|
||||
if (!RE->IgnoreParenImpCasts()->isLValue()) {
|
||||
Diag(ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
|
||||
SemaRef.Diag(ELoc,
|
||||
diag::err_omp_expected_named_var_member_or_array_expression)
|
||||
<< RE->getSourceRange();
|
||||
continue;
|
||||
}
|
||||
|
@ -10316,7 +10358,8 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
|
|||
|
||||
// Obtain the array or member expression bases if required. Also, fill the
|
||||
// components array with all the components identified in the process.
|
||||
auto *BE = CheckMapClauseExpressionBase(*this, SimpleExpr, CurComponents);
|
||||
auto *BE =
|
||||
CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind);
|
||||
if (!BE)
|
||||
continue;
|
||||
|
||||
|
@ -10340,50 +10383,55 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
|
|||
|
||||
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
|
||||
// threadprivate variables cannot appear in a map clause.
|
||||
if (VD && DSAStack->isThreadPrivate(VD)) {
|
||||
auto DVar = DSAStack->getTopDSA(VD, false);
|
||||
Diag(ELoc, diag::err_omp_threadprivate_in_map);
|
||||
ReportOriginalDSA(*this, DSAStack, VD, DVar);
|
||||
// OpenMP 4.5 [2.10.5, target update Construct]
|
||||
// threadprivate variables cannot appear in a from clause.
|
||||
if (VD && DSAS->isThreadPrivate(VD)) {
|
||||
auto DVar = DSAS->getTopDSA(VD, false);
|
||||
SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
|
||||
<< getOpenMPClauseName(CKind);
|
||||
ReportOriginalDSA(SemaRef, DSAS, VD, DVar);
|
||||
continue;
|
||||
}
|
||||
|
||||
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
|
||||
// A list item cannot appear in both a map clause and a data-sharing
|
||||
// attribute clause on the same construct.
|
||||
//
|
||||
// TODO: Implement this check - it cannot currently be tested because of
|
||||
// missing implementation of the other data sharing clauses in target
|
||||
// directives.
|
||||
|
||||
// Check conflicts with other map clause expressions. We check the conflicts
|
||||
// with the current construct separately from the enclosing data
|
||||
// environment, because the restrictions are different.
|
||||
if (CheckMapConflicts(*this, DSAStack, CurDeclaration, SimpleExpr,
|
||||
/*CurrentRegionOnly=*/true, CurComponents))
|
||||
// environment, because the restrictions are different. We only have to
|
||||
// check conflicts across regions for the map clauses.
|
||||
if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
|
||||
/*CurrentRegionOnly=*/true, CurComponents, CKind))
|
||||
break;
|
||||
if (CheckMapConflicts(*this, DSAStack, CurDeclaration, SimpleExpr,
|
||||
/*CurrentRegionOnly=*/false, CurComponents))
|
||||
if (CKind == OMPC_map &&
|
||||
CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
|
||||
/*CurrentRegionOnly=*/false, CurComponents, CKind))
|
||||
break;
|
||||
|
||||
// OpenMP 4.5 [2.10.5, target update Construct]
|
||||
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
|
||||
// If the type of a list item is a reference to a type T then the type will
|
||||
// be considered to be T for all purposes of this clause.
|
||||
QualType Type = CurDeclaration->getType().getNonReferenceType();
|
||||
|
||||
// OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
|
||||
// A list item in a to or from clause must have a mappable type.
|
||||
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
|
||||
// A list item must have a mappable type.
|
||||
if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), *this,
|
||||
DSAStack, Type))
|
||||
if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
|
||||
DSAS, Type))
|
||||
continue;
|
||||
|
||||
if (CKind == OMPC_map) {
|
||||
// target enter data
|
||||
// OpenMP [2.10.2, Restrictions, p. 99]
|
||||
// A map-type must be specified in all map clauses and must be either
|
||||
// to or alloc.
|
||||
OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
|
||||
OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
|
||||
if (DKind == OMPD_target_enter_data &&
|
||||
!(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
|
||||
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
|
||||
SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
|
||||
<< (IsMapTypeImplicit ? 1 : 0)
|
||||
<< getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
|
||||
<< getOpenMPDirectiveName(DKind);
|
||||
|
@ -10394,11 +10442,10 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
|
|||
// OpenMP [2.10.3, Restrictions, p. 102]
|
||||
// A map-type must be specified in all map clauses and must be either
|
||||
// from, release, or delete.
|
||||
DKind = DSAStack->getCurrentDirective();
|
||||
if (DKind == OMPD_target_exit_data &&
|
||||
!(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
|
||||
MapType == OMPC_MAP_delete)) {
|
||||
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
|
||||
SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
|
||||
<< (IsMapTypeImplicit ? 1 : 0)
|
||||
<< getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
|
||||
<< getOpenMPDirectiveName(DKind);
|
||||
|
@ -10409,37 +10456,51 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
|
|||
// A list item cannot appear in both a map clause and a data-sharing
|
||||
// attribute clause on the same construct
|
||||
if (DKind == OMPD_target && VD) {
|
||||
auto DVar = DSAStack->getTopDSA(VD, false);
|
||||
auto DVar = DSAS->getTopDSA(VD, false);
|
||||
if (isOpenMPPrivate(DVar.CKind)) {
|
||||
Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
|
||||
SemaRef.Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
|
||||
<< getOpenMPClauseName(DVar.CKind)
|
||||
<< getOpenMPDirectiveName(DSAStack->getCurrentDirective());
|
||||
ReportOriginalDSA(*this, DSAStack, CurDeclaration, DVar);
|
||||
<< getOpenMPDirectiveName(DSAS->getCurrentDirective());
|
||||
ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save the current expression.
|
||||
Vars.push_back(RE);
|
||||
MVLI.ProcessedVarList.push_back(RE);
|
||||
|
||||
// Store the components in the stack so that they can be used to check
|
||||
// against other clauses later on.
|
||||
DSAStack->addMappableExpressionComponents(CurDeclaration, CurComponents);
|
||||
DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents);
|
||||
|
||||
// Save the components and declaration to create the clause. For purposes of
|
||||
// the clause creation, any component list that has has base 'this' uses
|
||||
// null as base declaration.
|
||||
ClauseComponents.resize(ClauseComponents.size() + 1);
|
||||
ClauseComponents.back().append(CurComponents.begin(), CurComponents.end());
|
||||
ClauseBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
|
||||
MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
|
||||
MVLI.VarComponents.back().append(CurComponents.begin(),
|
||||
CurComponents.end());
|
||||
MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
|
||||
: CurDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
OMPClause *
|
||||
Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
|
||||
OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
|
||||
SourceLocation MapLoc, SourceLocation ColonLoc,
|
||||
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation EndLoc) {
|
||||
MappableVarListInfo MVLI(VarList);
|
||||
checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
|
||||
MapType, IsMapTypeImplicit);
|
||||
|
||||
// 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, Vars, ClauseBaseDeclarations,
|
||||
ClauseComponents, MapTypeModifier, MapType, IsMapTypeImplicit, MapLoc);
|
||||
return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
|
||||
MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
|
||||
MVLI.VarComponents, MapTypeModifier, MapType,
|
||||
IsMapTypeImplicit, MapLoc);
|
||||
}
|
||||
|
||||
QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
|
||||
|
@ -11042,3 +11103,17 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) {
|
|||
}
|
||||
checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc) {
|
||||
MappableVarListInfo MVLI(VarList);
|
||||
checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
|
||||
if (MVLI.ProcessedVarList.empty())
|
||||
return nullptr;
|
||||
|
||||
return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
|
||||
MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
|
||||
MVLI.VarComponents);
|
||||
}
|
||||
|
|
|
@ -1751,6 +1751,17 @@ public:
|
|||
Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new OpenMP 'to' clause.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new statement.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OMPClause *RebuildOMPToClause(ArrayRef<Expr *> VarList,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc) {
|
||||
return getSema().ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// \brief Rebuild the operand to an Objective-C \@synchronized statement.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new statement.
|
||||
|
@ -8038,6 +8049,20 @@ TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
|
|||
return C;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
|
||||
llvm::SmallVector<Expr *, 16> Vars;
|
||||
Vars.reserve(C->varlist_size());
|
||||
for (auto *VE : C->varlists()) {
|
||||
ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
|
||||
if (EVar.isInvalid())
|
||||
return 0;
|
||||
Vars.push_back(EVar.get());
|
||||
}
|
||||
return getDerived().RebuildOMPToClause(Vars, C->getLocStart(),
|
||||
C->getLParenLoc(), C->getLocEnd());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Expression transformation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -1894,6 +1894,15 @@ OMPClause *OMPClauseReader::readClause() {
|
|||
case OMPC_defaultmap:
|
||||
C = new (Context) OMPDefaultmapClause();
|
||||
break;
|
||||
case OMPC_to: {
|
||||
unsigned NumVars = Record[Idx++];
|
||||
unsigned NumDeclarations = Record[Idx++];
|
||||
unsigned NumLists = Record[Idx++];
|
||||
unsigned NumComponents = Record[Idx++];
|
||||
C = OMPToClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
|
||||
NumComponents);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Visit(C);
|
||||
C->setLocStart(Reader->ReadSourceLocation(Record, Idx));
|
||||
|
@ -2323,6 +2332,50 @@ void OMPClauseReader::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
|
|||
C->setDefaultmapKindLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPToClause(OMPToClause *C) {
|
||||
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
auto NumVars = C->varlist_size();
|
||||
auto UniqueDecls = C->getUniqueDeclarationsNum();
|
||||
auto TotalLists = C->getTotalComponentListNum();
|
||||
auto TotalComponents = C->getTotalComponentsNum();
|
||||
|
||||
SmallVector<Expr *, 16> Vars;
|
||||
Vars.reserve(NumVars);
|
||||
for (unsigned i = 0; i != NumVars; ++i)
|
||||
Vars.push_back(Reader->Reader.ReadSubExpr());
|
||||
C->setVarRefs(Vars);
|
||||
|
||||
SmallVector<ValueDecl *, 16> Decls;
|
||||
Decls.reserve(UniqueDecls);
|
||||
for (unsigned i = 0; i < UniqueDecls; ++i)
|
||||
Decls.push_back(
|
||||
Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx));
|
||||
C->setUniqueDecls(Decls);
|
||||
|
||||
SmallVector<unsigned, 16> ListsPerDecl;
|
||||
ListsPerDecl.reserve(UniqueDecls);
|
||||
for (unsigned i = 0; i < UniqueDecls; ++i)
|
||||
ListsPerDecl.push_back(Record[Idx++]);
|
||||
C->setDeclNumLists(ListsPerDecl);
|
||||
|
||||
SmallVector<unsigned, 32> ListSizes;
|
||||
ListSizes.reserve(TotalLists);
|
||||
for (unsigned i = 0; i < TotalLists; ++i)
|
||||
ListSizes.push_back(Record[Idx++]);
|
||||
C->setComponentListSizes(ListSizes);
|
||||
|
||||
SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
|
||||
Components.reserve(TotalComponents);
|
||||
for (unsigned i = 0; i < TotalComponents; ++i) {
|
||||
Expr *AssociatedExpr = Reader->Reader.ReadSubExpr();
|
||||
ValueDecl *AssociatedDecl =
|
||||
Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx);
|
||||
Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
|
||||
AssociatedExpr, AssociatedDecl));
|
||||
}
|
||||
C->setComponents(Components, ListSizes);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OpenMP Directives.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -2091,6 +2091,26 @@ void OMPClauseWriter::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
|
|||
Record.AddSourceLocation(C->getDefaultmapKindLoc());
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPToClause(OMPToClause *C) {
|
||||
Record.push_back(C->varlist_size());
|
||||
Record.push_back(C->getUniqueDeclarationsNum());
|
||||
Record.push_back(C->getTotalComponentListNum());
|
||||
Record.push_back(C->getTotalComponentsNum());
|
||||
Record.AddSourceLocation(C->getLParenLoc());
|
||||
for (auto *E : C->varlists())
|
||||
Record.AddStmt(E);
|
||||
for (auto *D : C->all_decls())
|
||||
Record.AddDeclRef(D);
|
||||
for (auto N : C->all_num_lists())
|
||||
Record.push_back(N);
|
||||
for (auto N : C->all_lists_sizes())
|
||||
Record.push_back(N);
|
||||
for (auto &M : C->all_components()) {
|
||||
Record.AddStmt(M.getAssociatedExpression());
|
||||
Record.AddDeclRef(M.getAssociatedDeclaration());
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OpenMP Directives.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -135,7 +135,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
}
|
||||
|
||||
// SIMD DIRECTIVE
|
||||
|
@ -299,7 +299,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
}
|
||||
|
||||
// FOR DIRECTIVE
|
||||
|
@ -486,7 +486,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp for
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
}
|
||||
|
||||
// FOR SIMD DIRECTIVE
|
||||
|
@ -650,7 +650,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
bar();
|
||||
}
|
||||
|
||||
|
@ -843,7 +843,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp sections
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
}
|
||||
|
||||
// SECTION DIRECTIVE
|
||||
|
@ -1088,7 +1088,7 @@ void foo() {
|
|||
#pragma omp section
|
||||
{
|
||||
bar();
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1266,7 +1266,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp single
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
bar();
|
||||
}
|
||||
|
||||
|
@ -1444,7 +1444,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp master
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
bar();
|
||||
}
|
||||
|
||||
|
@ -1636,7 +1636,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp critical
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
bar();
|
||||
}
|
||||
|
||||
|
@ -1829,7 +1829,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update //expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
}
|
||||
|
||||
// PARALLEL FOR SIMD DIRECTIVE
|
||||
|
@ -2021,7 +2021,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp parallel for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
bar();
|
||||
}
|
||||
|
||||
|
@ -2203,7 +2203,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp parallel sections
|
||||
{
|
||||
#pragma omp target update //expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
}
|
||||
|
||||
// TASK DIRECTIVE
|
||||
|
@ -2330,7 +2330,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp task
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
bar();
|
||||
}
|
||||
|
||||
|
@ -2529,7 +2529,7 @@ void foo() {
|
|||
#pragma omp ordered
|
||||
{
|
||||
bar();
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
bar();
|
||||
}
|
||||
|
||||
|
@ -2750,7 +2750,7 @@ void foo() {
|
|||
// expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
|
||||
// expected-note@+1 {{expected an expression statement}}
|
||||
{
|
||||
#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
|
||||
#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
|
||||
bar();
|
||||
}
|
||||
|
||||
|
@ -2889,7 +2889,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp target
|
||||
{
|
||||
#pragma omp target update // expected-error {{region cannot be nested inside 'target' region}}
|
||||
#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
|
||||
}
|
||||
|
||||
// TARGET PARALLEL DIRECTIVE
|
||||
|
@ -3027,7 +3027,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp target parallel
|
||||
{
|
||||
#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel' region}}
|
||||
#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel' region}}
|
||||
}
|
||||
|
||||
// TARGET PARALLEL FOR DIRECTIVE
|
||||
|
@ -3219,7 +3219,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp target parallel for
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel for' region}}
|
||||
#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel for' region}}
|
||||
}
|
||||
|
||||
// TEAMS DIRECTIVE
|
||||
|
@ -3387,7 +3387,7 @@ void foo() {
|
|||
#pragma omp target
|
||||
#pragma omp teams
|
||||
{
|
||||
#pragma omp target update // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
|
||||
#pragma omp target update to(a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
|
||||
}
|
||||
|
||||
// TASKLOOP DIRECTIVE
|
||||
|
@ -3563,7 +3563,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp taskloop
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
bar();
|
||||
}
|
||||
|
||||
|
@ -3789,7 +3789,7 @@ void foo() {
|
|||
#pragma omp teams
|
||||
#pragma omp distribute
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{region cannot be nested inside 'target' region}}
|
||||
#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
|
||||
++a;
|
||||
}
|
||||
}
|
||||
|
@ -3924,7 +3924,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
a++;
|
||||
}
|
||||
|
||||
|
@ -4082,7 +4082,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
a++;
|
||||
}
|
||||
|
||||
|
@ -4260,7 +4260,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp for
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
++a;
|
||||
}
|
||||
|
||||
|
@ -4418,7 +4418,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
++a;
|
||||
}
|
||||
|
||||
|
@ -4586,7 +4586,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp sections
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
}
|
||||
|
||||
// SECTION DIRECTIVE
|
||||
|
@ -4840,7 +4840,7 @@ void foo() {
|
|||
{
|
||||
#pragma omp section
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
a++;
|
||||
}
|
||||
}
|
||||
|
@ -5009,7 +5009,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp single
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
a++;
|
||||
}
|
||||
|
||||
|
@ -5187,7 +5187,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp master
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
++a;
|
||||
}
|
||||
|
||||
|
@ -5384,7 +5384,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp critical
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
a++;
|
||||
}
|
||||
|
||||
|
@ -5577,7 +5577,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
a++;
|
||||
}
|
||||
|
||||
|
@ -5770,7 +5770,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp parallel for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
a++;
|
||||
}
|
||||
|
||||
|
@ -5948,7 +5948,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp parallel sections
|
||||
{
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
}
|
||||
|
||||
// TASK DIRECTIVE
|
||||
|
@ -6074,7 +6074,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp task
|
||||
{
|
||||
#pragma omp target update // // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
a++;
|
||||
}
|
||||
|
||||
|
@ -6435,7 +6435,7 @@ void foo() {
|
|||
// expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
|
||||
// expected-note@+1 {{expected an expression statement}}
|
||||
{
|
||||
#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
|
||||
#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
|
||||
a++;
|
||||
}
|
||||
|
||||
|
@ -6574,7 +6574,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp target parallel
|
||||
{
|
||||
#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel' region}}
|
||||
#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel' region}}
|
||||
}
|
||||
|
||||
|
||||
|
@ -6767,7 +6767,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp target parallel for
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{region cannot be nested inside 'target parallel for' region}}
|
||||
#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel for' region}}
|
||||
a++;
|
||||
}
|
||||
|
||||
|
@ -6934,7 +6934,7 @@ void foo() {
|
|||
#pragma omp target
|
||||
#pragma omp teams
|
||||
{
|
||||
#pragma omp target update // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
|
||||
#pragma omp target update to(a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
|
||||
++a;
|
||||
}
|
||||
|
||||
|
@ -7111,7 +7111,7 @@ void foo() {
|
|||
}
|
||||
#pragma omp taskloop
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a)
|
||||
++a;
|
||||
}
|
||||
|
||||
|
@ -7337,7 +7337,7 @@ void foo() {
|
|||
#pragma omp teams
|
||||
#pragma omp distribute
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp target update // expected-error {{region cannot be nested inside 'target' region}}
|
||||
#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
|
||||
++a;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ struct SA {
|
|||
#pragma omp target map(arg,a,d[:2]) // expected-error {{subscripted value is not an array or pointer}}
|
||||
{}
|
||||
|
||||
#pragma omp target map(to:ss) // expected-error {{threadprivate variables are not allowed in map clause}}
|
||||
#pragma omp target map(to:ss) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
|
||||
{}
|
||||
|
||||
#pragma omp target map(to:b,e)
|
||||
|
@ -239,7 +239,7 @@ void SAclient(int arg) {
|
|||
{}
|
||||
#pragma omp target map(r.C, t.C)
|
||||
{}
|
||||
#pragma omp target map(r.A) // expected-error {{bit fields cannot be used to specify storage in a map clause}}
|
||||
#pragma omp target map(r.A) // expected-error {{bit fields cannot be used to specify storage in a 'map' clause}}
|
||||
{}
|
||||
#pragma omp target map(r.Arr)
|
||||
{}
|
||||
|
@ -407,7 +407,7 @@ T tmain(T argc) {
|
|||
#pragma omp target data map(S2::S2s)
|
||||
#pragma omp target data map(S2::S2sc)
|
||||
#pragma omp target data map(e, g)
|
||||
#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in map clause}}
|
||||
#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
|
||||
#pragma omp target data map(k) map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
|
||||
#pragma omp target map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
|
||||
foo();
|
||||
|
@ -476,7 +476,7 @@ int main(int argc, char **argv) {
|
|||
#pragma omp target data map(S2::S2s)
|
||||
#pragma omp target data map(S2::S2sc)
|
||||
#pragma omp target data map(e, g)
|
||||
#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in map clause}}
|
||||
#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
|
||||
#pragma omp target data map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
|
||||
#pragma omp target map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
|
||||
foo();
|
||||
|
|
|
@ -126,7 +126,7 @@ T tmain(T argc) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(e, g)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(h) // expected-error {{threadprivate variables are not allowed in map clause}}
|
||||
#pragma omp target parallel for map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
@ -230,7 +230,7 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(e, g)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(h) // expected-error {{threadprivate variables are not allowed in map clause}}
|
||||
#pragma omp target parallel for map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
|
|
@ -126,7 +126,7 @@ T tmain(T argc) {
|
|||
foo();
|
||||
#pragma omp target parallel map(e, g)
|
||||
foo();
|
||||
#pragma omp target parallel map(h) // expected-error {{threadprivate variables are not allowed in map clause}}
|
||||
#pragma omp target parallel map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
|
||||
foo();
|
||||
#pragma omp target parallel map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
|
||||
foo();
|
||||
|
@ -229,7 +229,7 @@ int main(int argc, char **argv) {
|
|||
foo();
|
||||
#pragma omp target parallel map(e, g)
|
||||
foo();
|
||||
#pragma omp target parallel map(h) // expected-error {{threadprivate variables are not allowed in map clause}}
|
||||
#pragma omp target parallel map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
|
||||
foo();
|
||||
#pragma omp target parallel map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
|
||||
foo();
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
void foo() {}
|
||||
|
||||
template <class T, class U>
|
||||
T foo(T targ, U uarg) {
|
||||
static T a;
|
||||
U b;
|
||||
int l;
|
||||
#pragma omp target update to(a) if(l>5) device(l)
|
||||
return a + targ + (T)b;
|
||||
}
|
||||
// CHECK: static int a;
|
||||
// CHECK-NEXT: float b;
|
||||
// CHECK-NEXT: int l;
|
||||
// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l)
|
||||
// CHECK: static char a;
|
||||
// CHECK-NEXT: float b;
|
||||
// CHECK-NEXT: int l;
|
||||
// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l)
|
||||
// CHECK: static T a;
|
||||
// CHECK-NEXT: U b;
|
||||
// CHECK-NEXT: int l;
|
||||
// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l)
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
static int a;
|
||||
int n;
|
||||
float f;
|
||||
|
||||
// CHECK: static int a;
|
||||
// CHECK-NEXT: int n;
|
||||
// CHECK-NEXT: float f;
|
||||
#pragma omp target update to(a) if(f>0.0) device(n)
|
||||
// CHECK-NEXT: #pragma omp target update to(a) if(f > 0.) device(n)
|
||||
return foo(argc, f) + foo(argv[0][0], f) + a;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -12,11 +12,11 @@ struct S1; // expected-note 2 {{declared here}}
|
|||
template <class T, class S>
|
||||
int tmain(T argc, S **argv) {
|
||||
int i;
|
||||
#pragma omp target update device // expected-error {{expected '(' after 'device'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(i) device // expected-error {{expected '(' after 'device'}}
|
||||
#pragma omp target update to(i) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target update to(i) device () // expected-error {{expected expression}}
|
||||
#pragma omp target update to(i) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target update to(i) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
|
||||
#pragma omp target update device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device (argc + argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
|
@ -27,17 +27,17 @@ int tmain(T argc, S **argv) {
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
int j;
|
||||
#pragma omp target update device // expected-error {{expected '(' after 'device'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(j) device // expected-error {{expected '(' after 'device'}}
|
||||
#pragma omp target update device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(j) device () // expected-error {{expected expression}}
|
||||
#pragma omp target update device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(j) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
|
||||
#pragma omp target update device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device (argc + argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(j) device (argc + argc)
|
||||
#pragma omp target update device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device (S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(j) device (S1) // expected-error {{'S1' does not refer to a value}}
|
||||
#pragma omp target update device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(j) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
|
||||
|
||||
return tmain(argc, argv);
|
||||
}
|
||||
|
|
|
@ -12,47 +12,47 @@ struct S1; // expected-note {{declared here}}
|
|||
template <class T, class S> // expected-note {{declared here}}
|
||||
int tmain(T argc, S **argv) {
|
||||
int n;
|
||||
#pragma omp target update if // expected-error {{expected '(' after 'if'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(n) if // expected-error {{expected '(' after 'if'}}
|
||||
#pragma omp target update if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(n) if () // expected-error {{expected expression}}
|
||||
#pragma omp target update if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(n) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
|
||||
#pragma omp target update if (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(n) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}}
|
||||
#pragma omp target update if (S) // expected-error {{'S' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(n) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target update if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if(argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(n) if(argc)
|
||||
#pragma omp target update if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(n) if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target update if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if(target update : argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(n) if(target update : argc)
|
||||
#pragma omp target update if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(n) if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}}
|
||||
#pragma omp target update if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int m;
|
||||
#pragma omp target update if // expected-error {{expected '(' after 'if'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if // expected-error {{expected '(' after 'if'}}
|
||||
#pragma omp target update if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if () // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if () // expected-error {{expected expression}}
|
||||
#pragma omp target update if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
|
||||
#pragma omp target update if (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}}
|
||||
#pragma omp target update if (S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target update if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target update if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target update if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target update if(target update : argc) // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}}
|
||||
#pragma omp target update if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
|
||||
return tmain(argc, argv);
|
||||
}
|
||||
|
|
|
@ -18,13 +18,13 @@ int tmain(T argc, S **argv) {
|
|||
int main(int argc, char **argv) {
|
||||
int m;
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update { // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update ( // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update [ // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update ] // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update ) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) { // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
|
||||
#pragma omp target update to(m) ( // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
|
||||
#pragma omp target update to(m) [ // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
|
||||
#pragma omp target update to(m) ] // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
|
||||
#pragma omp target update to(m) ) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
|
||||
|
||||
#pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(m) // OK
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
|
||||
|
||||
void foo() {
|
||||
}
|
||||
|
||||
bool foobool(int argc) {
|
||||
return argc;
|
||||
}
|
||||
|
||||
struct S1; // expected-note 2 {{declared here}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
mutable int a;
|
||||
public:
|
||||
S2():a(0) { }
|
||||
S2(S2 &s2):a(s2.a) { }
|
||||
static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
|
||||
static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
|
||||
};
|
||||
const float S2::S2sc = 0;
|
||||
const S2 b;
|
||||
const S2 ba[5];
|
||||
class S3 {
|
||||
int a;
|
||||
public:
|
||||
S3():a(0) { }
|
||||
S3(S3 &s3):a(s3.a) { }
|
||||
};
|
||||
const S3 c;
|
||||
const S3 ca[5];
|
||||
extern const int f;
|
||||
class S4 {
|
||||
int a;
|
||||
S4();
|
||||
S4(const S4 &s4);
|
||||
public:
|
||||
S4(int v):a(v) { }
|
||||
};
|
||||
class S5 {
|
||||
int a;
|
||||
S5():a(0) {}
|
||||
S5(const S5 &s5):a(s5.a) { }
|
||||
public:
|
||||
S5(int v):a(v) { }
|
||||
};
|
||||
struct S6 {
|
||||
int ii;
|
||||
int aa[30];
|
||||
float xx;
|
||||
double *pp;
|
||||
};
|
||||
struct S7 {
|
||||
int i;
|
||||
int a[50];
|
||||
float x;
|
||||
S6 s6[5];
|
||||
double *p;
|
||||
unsigned bfa : 4;
|
||||
};
|
||||
|
||||
S3 h;
|
||||
#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
|
||||
|
||||
typedef int from;
|
||||
|
||||
template <typename T, int I> // expected-note {{declared here}}
|
||||
T tmain(T argc) {
|
||||
const T d = 5;
|
||||
const T da[5] = { 0 };
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
T *m;
|
||||
T i, t[20];
|
||||
T &j = i;
|
||||
T *k = &j;
|
||||
T x;
|
||||
T y;
|
||||
T to;
|
||||
const T (&l)[5] = da;
|
||||
S7 s7;
|
||||
|
||||
#pragma omp target update to // expected-error {{expected '(' after 'to'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(x)
|
||||
#pragma omp target update to(t[:I])
|
||||
#pragma omp target update to(T) // expected-error {{'T' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
|
||||
#pragma omp target update to(S2::S2s)
|
||||
#pragma omp target update to(S2::S2sc)
|
||||
#pragma omp target update to(to)
|
||||
#pragma omp target update to(y x) // expected-error {{expected ',' or ')' in 'to' clause}}
|
||||
#pragma omp target update to(argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
|
||||
#pragma omp target update to(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
|
||||
#pragma omp target update to(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(h) // expected-error {{threadprivate variables are not allowed in 'to' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(k), to(k) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
|
||||
#pragma omp target update to(t), to(t[:5]) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
|
||||
#pragma omp target update to(da)
|
||||
#pragma omp target update to(da[:4])
|
||||
|
||||
#pragma omp target update to(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}}
|
||||
#pragma omp target update to(x, c[:]) // expected-error {{subscripted value is not an array or pointer}}
|
||||
#pragma omp target update to(x, (m+1)[2]) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
|
||||
#pragma omp target update to(s7.i, s7.a[:3])
|
||||
#pragma omp target update to(s7.s6[1].aa[0:5])
|
||||
#pragma omp target update to(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
|
||||
#pragma omp target update to(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
|
||||
#pragma omp target update to(s7.p[:10])
|
||||
#pragma omp target update to(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'to' clause}}
|
||||
#pragma omp target update to(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
|
||||
#pragma omp target data map(to: s7.i)
|
||||
{
|
||||
#pragma omp target update to(s7.x)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
const int d = 5;
|
||||
const int da[5] = { 0 };
|
||||
S4 e(4);
|
||||
S5 g(5);
|
||||
int i, t[20];
|
||||
int &j = i;
|
||||
int *k = &j;
|
||||
int x;
|
||||
int y;
|
||||
int to;
|
||||
const int (&l)[5] = da;
|
||||
S7 s7;
|
||||
int *m;
|
||||
|
||||
#pragma omp target update to // expected-error {{expected '(' after 'to'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(x)
|
||||
#pragma omp target update to(t[:i])
|
||||
#pragma omp target update to(S2::S2s)
|
||||
#pragma omp target update to(S2::S2sc)
|
||||
#pragma omp target update to(to)
|
||||
#pragma omp target update to(y x) // expected-error {{expected ',' or ')' in 'to' clause}}
|
||||
#pragma omp target update to(argc > 0 ? x : y) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
|
||||
#pragma omp target update to(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(h) // expected-error {{threadprivate variables are not allowed in 'to' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
|
||||
#pragma omp target update to(k), to(k) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
|
||||
#pragma omp target update to(t), to(t[:5]) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
|
||||
#pragma omp target update to(da)
|
||||
#pragma omp target update to(da[:4])
|
||||
|
||||
#pragma omp target update to(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}}
|
||||
#pragma omp target update to(x, c[:]) // expected-error {{subscripted value is not an array or pointer}}
|
||||
#pragma omp target update to(x, (m+1)[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
|
||||
#pragma omp target update to(s7.i, s7.a[:3])
|
||||
#pragma omp target update to(s7.s6[1].aa[0:5])
|
||||
#pragma omp target update to(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
|
||||
#pragma omp target update to(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
|
||||
#pragma omp target update to(s7.p[:10])
|
||||
#pragma omp target update to(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'to' clause}}
|
||||
#pragma omp target update to(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
|
||||
#pragma omp target data map(to: s7.i)
|
||||
{
|
||||
#pragma omp target update to(s7.x)
|
||||
}
|
||||
|
||||
return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
|
||||
}
|
||||
|
|
@ -2246,6 +2246,9 @@ void OMPClauseEnqueue::VisitOMPDistScheduleClause(
|
|||
}
|
||||
void OMPClauseEnqueue::VisitOMPDefaultmapClause(
|
||||
const OMPDefaultmapClause * /*C*/) {}
|
||||
void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
}
|
||||
}
|
||||
|
||||
void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
|
||||
|
|
Loading…
Reference in New Issue