forked from OSchip/llvm-project
[OPENMP50]Add parsing/sema for acq_rel clause.
Added basic support (representation + parsing/sema/(de)serialization) for acq_rel clause in flush/atomic directives.
This commit is contained in:
parent
2db5547c01
commit
ea9166b5a8
|
@ -1875,6 +1875,46 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// This represents 'acq_rel' clause in the '#pragma omp atomic|flush'
|
||||||
|
/// directives.
|
||||||
|
///
|
||||||
|
/// \code
|
||||||
|
/// #pragma omp flush acq_rel
|
||||||
|
/// \endcode
|
||||||
|
/// In this example directive '#pragma omp flush' has 'acq_rel' clause.
|
||||||
|
class OMPAcqRelClause : public OMPClause {
|
||||||
|
public:
|
||||||
|
/// Build 'ack_rel' clause.
|
||||||
|
///
|
||||||
|
/// \param StartLoc Starting location of the clause.
|
||||||
|
/// \param EndLoc Ending location of the clause.
|
||||||
|
OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc)
|
||||||
|
: OMPClause(OMPC_acq_rel, StartLoc, EndLoc) {}
|
||||||
|
|
||||||
|
/// Build an empty clause.
|
||||||
|
OMPAcqRelClause()
|
||||||
|
: OMPClause(OMPC_acq_rel, SourceLocation(), SourceLocation()) {}
|
||||||
|
|
||||||
|
child_range children() {
|
||||||
|
return child_range(child_iterator(), child_iterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_child_range children() const {
|
||||||
|
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
child_range used_children() {
|
||||||
|
return child_range(child_iterator(), child_iterator());
|
||||||
|
}
|
||||||
|
const_child_range used_children() const {
|
||||||
|
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool classof(const OMPClause *T) {
|
||||||
|
return T->getClauseKind() == OMPC_acq_rel;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// This represents clause 'private' in the '#pragma omp ...' directives.
|
/// This represents clause 'private' in the '#pragma omp ...' directives.
|
||||||
///
|
///
|
||||||
/// \code
|
/// \code
|
||||||
|
|
|
@ -3121,6 +3121,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Derived>
|
||||||
|
bool RecursiveASTVisitor<Derived>::VisitOMPAcqRelClause(OMPAcqRelClause *) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Derived>
|
template <typename Derived>
|
||||||
bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
|
bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -9656,6 +9656,8 @@ def note_omp_atomic_capture: Note<
|
||||||
"%select{expected assignment expression|expected compound statement|expected exactly two expression statements|expected in right hand side of the first expression}0">;
|
"%select{expected assignment expression|expected compound statement|expected exactly two expression statements|expected in right hand side of the first expression}0">;
|
||||||
def err_omp_atomic_several_clauses : Error<
|
def err_omp_atomic_several_clauses : Error<
|
||||||
"directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">;
|
"directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">;
|
||||||
|
def err_omp_atomic_several_mem_order_clauses : Error<
|
||||||
|
"directive '#pragma omp atomic' cannot contain more than one 'seq_cst' or 'acq_rel' clause">;
|
||||||
def note_omp_atomic_previous_clause : Note<
|
def note_omp_atomic_previous_clause : Note<
|
||||||
"'%0' clause used here">;
|
"'%0' clause used here">;
|
||||||
def err_omp_target_contains_not_only_teams : Error<
|
def err_omp_target_contains_not_only_teams : Error<
|
||||||
|
@ -9894,6 +9896,10 @@ def err_omp_one_defaultmap_each_category: Error<
|
||||||
def err_omp_lastprivate_conditional_non_scalar : Error<
|
def err_omp_lastprivate_conditional_non_scalar : Error<
|
||||||
"expected list item of scalar type in 'lastprivate' clause with 'conditional' modifier"
|
"expected list item of scalar type in 'lastprivate' clause with 'conditional' modifier"
|
||||||
>;
|
>;
|
||||||
|
def err_omp_flush_order_clause_and_list : Error<
|
||||||
|
"'flush' directive with memory order clause '%0' cannot have the list">;
|
||||||
|
def note_omp_flush_order_clause_here : Note<
|
||||||
|
"memory order clause '%0' is specified here">;
|
||||||
} // end of OpenMP category
|
} // end of OpenMP category
|
||||||
|
|
||||||
let CategoryName = "Related Result Type Issue" in {
|
let CategoryName = "Related Result Type Issue" in {
|
||||||
|
|
|
@ -215,6 +215,9 @@
|
||||||
#ifndef OPENMP_ORDER_KIND
|
#ifndef OPENMP_ORDER_KIND
|
||||||
#define OPENMP_ORDER_KIND(Name)
|
#define OPENMP_ORDER_KIND(Name)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef OPENMP_FLUSH_CLAUSE
|
||||||
|
#define OPENMP_FLUSH_CLAUSE(Name)
|
||||||
|
#endif
|
||||||
|
|
||||||
// OpenMP context selector sets.
|
// OpenMP context selector sets.
|
||||||
OPENMP_CONTEXT_SELECTOR_SET(implementation)
|
OPENMP_CONTEXT_SELECTOR_SET(implementation)
|
||||||
|
@ -254,6 +257,7 @@ OPENMP_CLAUSE(write, OMPWriteClause)
|
||||||
OPENMP_CLAUSE(update, OMPUpdateClause)
|
OPENMP_CLAUSE(update, OMPUpdateClause)
|
||||||
OPENMP_CLAUSE(capture, OMPCaptureClause)
|
OPENMP_CLAUSE(capture, OMPCaptureClause)
|
||||||
OPENMP_CLAUSE(seq_cst, OMPSeqCstClause)
|
OPENMP_CLAUSE(seq_cst, OMPSeqCstClause)
|
||||||
|
OPENMP_CLAUSE(acq_rel, OMPAcqRelClause)
|
||||||
OPENMP_CLAUSE(depend, OMPDependClause)
|
OPENMP_CLAUSE(depend, OMPDependClause)
|
||||||
OPENMP_CLAUSE(device, OMPDeviceClause)
|
OPENMP_CLAUSE(device, OMPDeviceClause)
|
||||||
OPENMP_CLAUSE(threads, OMPThreadsClause)
|
OPENMP_CLAUSE(threads, OMPThreadsClause)
|
||||||
|
@ -486,6 +490,7 @@ OPENMP_ATOMIC_CLAUSE(write)
|
||||||
OPENMP_ATOMIC_CLAUSE(update)
|
OPENMP_ATOMIC_CLAUSE(update)
|
||||||
OPENMP_ATOMIC_CLAUSE(capture)
|
OPENMP_ATOMIC_CLAUSE(capture)
|
||||||
OPENMP_ATOMIC_CLAUSE(seq_cst)
|
OPENMP_ATOMIC_CLAUSE(seq_cst)
|
||||||
|
OPENMP_ATOMIC_CLAUSE(acq_rel)
|
||||||
|
|
||||||
// Clauses allowed for OpenMP directive 'target'.
|
// Clauses allowed for OpenMP directive 'target'.
|
||||||
OPENMP_TARGET_CLAUSE(if)
|
OPENMP_TARGET_CLAUSE(if)
|
||||||
|
@ -1082,6 +1087,10 @@ OPENMP_LASTPRIVATE_KIND(conditional)
|
||||||
// Type of the 'order' clause.
|
// Type of the 'order' clause.
|
||||||
OPENMP_ORDER_KIND(concurrent)
|
OPENMP_ORDER_KIND(concurrent)
|
||||||
|
|
||||||
|
// Clauses allowed for OpenMP directive 'flush'.
|
||||||
|
OPENMP_FLUSH_CLAUSE(acq_rel)
|
||||||
|
|
||||||
|
#undef OPENMP_FLUSH_CLAUSE
|
||||||
#undef OPENMP_ORDER_KIND
|
#undef OPENMP_ORDER_KIND
|
||||||
#undef OPENMP_LASTPRIVATE_KIND
|
#undef OPENMP_LASTPRIVATE_KIND
|
||||||
#undef OPENMP_CONTEXT_SELECTOR
|
#undef OPENMP_CONTEXT_SELECTOR
|
||||||
|
|
|
@ -10327,6 +10327,9 @@ public:
|
||||||
/// Called on well-formed 'seq_cst' clause.
|
/// Called on well-formed 'seq_cst' clause.
|
||||||
OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
|
OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
|
||||||
SourceLocation EndLoc);
|
SourceLocation EndLoc);
|
||||||
|
/// Called on well-formed 'acq_rel' clause.
|
||||||
|
OMPClause *ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
|
||||||
|
SourceLocation EndLoc);
|
||||||
/// Called on well-formed 'threads' clause.
|
/// Called on well-formed 'threads' clause.
|
||||||
OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc,
|
OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc,
|
||||||
SourceLocation EndLoc);
|
SourceLocation EndLoc);
|
||||||
|
|
|
@ -116,6 +116,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_depend:
|
case OMPC_depend:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
case OMPC_simd:
|
case OMPC_simd:
|
||||||
|
@ -190,6 +191,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_depend:
|
case OMPC_depend:
|
||||||
case OMPC_device:
|
case OMPC_device:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
|
@ -1334,6 +1336,10 @@ void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
|
||||||
OS << "seq_cst";
|
OS << "seq_cst";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
|
||||||
|
OS << "acq_rel";
|
||||||
|
}
|
||||||
|
|
||||||
void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
|
void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
|
||||||
OS << "threads";
|
OS << "threads";
|
||||||
}
|
}
|
||||||
|
|
|
@ -517,6 +517,8 @@ void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
|
||||||
|
|
||||||
void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
|
void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
|
||||||
|
|
||||||
|
void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
|
||||||
|
|
||||||
void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {}
|
void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {}
|
||||||
|
|
||||||
void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {}
|
void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {}
|
||||||
|
|
|
@ -214,6 +214,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_device:
|
case OMPC_device:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
case OMPC_simd:
|
case OMPC_simd:
|
||||||
|
@ -426,6 +427,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_device:
|
case OMPC_device:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
case OMPC_simd:
|
case OMPC_simd:
|
||||||
|
@ -577,9 +579,22 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OMPD_flush:
|
case OMPD_flush:
|
||||||
return CKind == OMPC_flush;
|
if (CKind == OMPC_flush)
|
||||||
|
return true;
|
||||||
|
if (OpenMPVersion < 50)
|
||||||
|
return false;
|
||||||
|
switch (CKind) {
|
||||||
|
#define OPENMP_FLUSH_CLAUSE(Name) \
|
||||||
|
case OMPC_##Name: \
|
||||||
|
return true;
|
||||||
|
#include "clang/Basic/OpenMPKinds.def"
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OMPD_atomic:
|
case OMPD_atomic:
|
||||||
|
if (OpenMPVersion < 50 && CKind == OMPC_acq_rel)
|
||||||
|
return false;
|
||||||
switch (CKind) {
|
switch (CKind) {
|
||||||
#define OPENMP_ATOMIC_CLAUSE(Name) \
|
#define OPENMP_ATOMIC_CLAUSE(Name) \
|
||||||
case OMPC_##Name: \
|
case OMPC_##Name: \
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "clang/AST/OpenMPClause.h"
|
#include "clang/AST/OpenMPClause.h"
|
||||||
#include "clang/AST/Stmt.h"
|
#include "clang/AST/Stmt.h"
|
||||||
#include "clang/AST/StmtOpenMP.h"
|
#include "clang/AST/StmtOpenMP.h"
|
||||||
|
#include "clang/Basic/OpenMPKinds.h"
|
||||||
#include "clang/Basic/PrettyStackTrace.h"
|
#include "clang/Basic/PrettyStackTrace.h"
|
||||||
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
|
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
@ -4434,6 +4435,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
|
||||||
case OMPC_collapse:
|
case OMPC_collapse:
|
||||||
case OMPC_default:
|
case OMPC_default:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_shared:
|
case OMPC_shared:
|
||||||
case OMPC_linear:
|
case OMPC_linear:
|
||||||
case OMPC_aligned:
|
case OMPC_aligned:
|
||||||
|
@ -4483,8 +4485,9 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
|
||||||
bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>();
|
bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>();
|
||||||
OpenMPClauseKind Kind = OMPC_unknown;
|
OpenMPClauseKind Kind = OMPC_unknown;
|
||||||
for (const OMPClause *C : S.clauses()) {
|
for (const OMPClause *C : S.clauses()) {
|
||||||
// Find first clause (skip seq_cst clause, if it is first).
|
// Find first clause (skip seq_cst|acq_rel clause, if it is first).
|
||||||
if (C->getClauseKind() != OMPC_seq_cst) {
|
if (C->getClauseKind() != OMPC_seq_cst &&
|
||||||
|
C->getClauseKind() != OMPC_acq_rel) {
|
||||||
Kind = C->getClauseKind();
|
Kind = C->getClauseKind();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1720,7 +1720,6 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
|
||||||
DeclarationNameInfo DirName;
|
DeclarationNameInfo DirName;
|
||||||
StmtResult Directive = StmtError();
|
StmtResult Directive = StmtError();
|
||||||
bool HasAssociatedStatement = true;
|
bool HasAssociatedStatement = true;
|
||||||
bool FlushHasClause = false;
|
|
||||||
|
|
||||||
switch (DKind) {
|
switch (DKind) {
|
||||||
case OMPD_threadprivate: {
|
case OMPD_threadprivate: {
|
||||||
|
@ -1831,13 +1830,6 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OMPD_flush:
|
case OMPD_flush:
|
||||||
if (PP.LookAhead(0).is(tok::l_paren)) {
|
|
||||||
FlushHasClause = true;
|
|
||||||
// Push copy of the current token back to stream to properly parse
|
|
||||||
// pseudo-clause OMPFlushClause.
|
|
||||||
PP.EnterToken(Tok, /*IsReinject*/ true);
|
|
||||||
}
|
|
||||||
LLVM_FALLTHROUGH;
|
|
||||||
case OMPD_taskyield:
|
case OMPD_taskyield:
|
||||||
case OMPD_barrier:
|
case OMPD_barrier:
|
||||||
case OMPD_taskwait:
|
case OMPD_taskwait:
|
||||||
|
@ -1897,6 +1889,10 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
|
||||||
case OMPD_target_teams_distribute_parallel_for:
|
case OMPD_target_teams_distribute_parallel_for:
|
||||||
case OMPD_target_teams_distribute_parallel_for_simd:
|
case OMPD_target_teams_distribute_parallel_for_simd:
|
||||||
case OMPD_target_teams_distribute_simd: {
|
case OMPD_target_teams_distribute_simd: {
|
||||||
|
// Special processing for flush clause.
|
||||||
|
Token FlushTok;
|
||||||
|
if (DKind == OMPD_flush)
|
||||||
|
FlushTok = Tok;
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
// Parse directive name of the 'critical' directive if any.
|
// Parse directive name of the 'critical' directive if any.
|
||||||
if (DKind == OMPD_critical) {
|
if (DKind == OMPD_critical) {
|
||||||
|
@ -1926,6 +1922,15 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
|
||||||
Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
|
Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
|
||||||
|
|
||||||
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||||
|
bool FlushHasClause = false;
|
||||||
|
if (DKind == OMPD_flush && Tok.is(tok::l_paren)) {
|
||||||
|
FlushHasClause = true;
|
||||||
|
// Push copy of the current token back to stream to properly parse
|
||||||
|
// pseudo-clause OMPFlushClause.
|
||||||
|
PP.EnterToken(Tok, /*IsReinject*/ true);
|
||||||
|
PP.EnterToken(FlushTok, /*IsReinject*/ true);
|
||||||
|
ConsumeAnyToken();
|
||||||
|
}
|
||||||
OpenMPClauseKind CKind =
|
OpenMPClauseKind CKind =
|
||||||
Tok.isAnnotation()
|
Tok.isAnnotation()
|
||||||
? OMPC_unknown
|
? OMPC_unknown
|
||||||
|
@ -2084,7 +2089,8 @@ bool Parser::ParseOpenMPSimpleVarList(
|
||||||
/// thread_limit-clause | priority-clause | grainsize-clause |
|
/// thread_limit-clause | priority-clause | grainsize-clause |
|
||||||
/// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
|
/// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
|
||||||
/// from-clause | is_device_ptr-clause | task_reduction-clause |
|
/// from-clause | is_device_ptr-clause | task_reduction-clause |
|
||||||
/// in_reduction-clause | allocator-clause | allocate-clause
|
/// in_reduction-clause | allocator-clause | allocate-clause |
|
||||||
|
/// acq_rel-clause
|
||||||
///
|
///
|
||||||
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
||||||
OpenMPClauseKind CKind, bool FirstClause) {
|
OpenMPClauseKind CKind, bool FirstClause) {
|
||||||
|
@ -2193,6 +2199,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
case OMPC_simd:
|
case OMPC_simd:
|
||||||
case OMPC_nogroup:
|
case OMPC_nogroup:
|
||||||
|
|
|
@ -4987,6 +4987,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_depend:
|
case OMPC_depend:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
case OMPC_simd:
|
case OMPC_simd:
|
||||||
|
@ -8562,7 +8563,21 @@ StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
|
||||||
StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
|
StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
|
||||||
SourceLocation StartLoc,
|
SourceLocation StartLoc,
|
||||||
SourceLocation EndLoc) {
|
SourceLocation EndLoc) {
|
||||||
assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
|
OMPFlushClause *FC = nullptr;
|
||||||
|
OMPClause *OrderClause = nullptr;
|
||||||
|
for (OMPClause *C : Clauses) {
|
||||||
|
if (C->getClauseKind() == OMPC_flush)
|
||||||
|
FC = cast<OMPFlushClause>(C);
|
||||||
|
else
|
||||||
|
OrderClause = C;
|
||||||
|
}
|
||||||
|
if (FC && OrderClause) {
|
||||||
|
Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
|
||||||
|
<< getOpenMPClauseName(OrderClause->getClauseKind());
|
||||||
|
Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
|
||||||
|
<< getOpenMPClauseName(OrderClause->getClauseKind());
|
||||||
|
return StmtError();
|
||||||
|
}
|
||||||
return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
|
return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8901,6 +8916,8 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
|
||||||
// longjmp() and throw() must not violate the entry/exit criteria.
|
// longjmp() and throw() must not violate the entry/exit criteria.
|
||||||
OpenMPClauseKind AtomicKind = OMPC_unknown;
|
OpenMPClauseKind AtomicKind = OMPC_unknown;
|
||||||
SourceLocation AtomicKindLoc;
|
SourceLocation AtomicKindLoc;
|
||||||
|
OpenMPClauseKind MemOrderKind = OMPC_unknown;
|
||||||
|
SourceLocation MemOrderLoc;
|
||||||
for (const OMPClause *C : Clauses) {
|
for (const OMPClause *C : Clauses) {
|
||||||
if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
|
if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
|
||||||
C->getClauseKind() == OMPC_update ||
|
C->getClauseKind() == OMPC_update ||
|
||||||
|
@ -8915,6 +8932,18 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
|
||||||
AtomicKindLoc = C->getBeginLoc();
|
AtomicKindLoc = C->getBeginLoc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (C->getClauseKind() == OMPC_seq_cst ||
|
||||||
|
C->getClauseKind() == OMPC_acq_rel) {
|
||||||
|
if (MemOrderKind != OMPC_unknown) {
|
||||||
|
Diag(C->getBeginLoc(), diag::err_omp_atomic_several_mem_order_clauses)
|
||||||
|
<< SourceRange(C->getBeginLoc(), C->getEndLoc());
|
||||||
|
Diag(MemOrderLoc, diag::note_omp_atomic_previous_clause)
|
||||||
|
<< getOpenMPClauseName(MemOrderKind);
|
||||||
|
} else {
|
||||||
|
MemOrderKind = C->getClauseKind();
|
||||||
|
MemOrderLoc = C->getBeginLoc();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stmt *Body = CS->getCapturedStmt();
|
Stmt *Body = CS->getCapturedStmt();
|
||||||
|
@ -10841,6 +10870,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_depend:
|
case OMPC_depend:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
case OMPC_simd:
|
case OMPC_simd:
|
||||||
|
@ -11553,6 +11583,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_depend:
|
case OMPC_depend:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
case OMPC_simd:
|
case OMPC_simd:
|
||||||
|
@ -11975,6 +12006,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_depend:
|
case OMPC_depend:
|
||||||
case OMPC_device:
|
case OMPC_device:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
|
@ -12175,6 +12207,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_depend:
|
case OMPC_depend:
|
||||||
case OMPC_device:
|
case OMPC_device:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
|
@ -12348,6 +12381,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
|
Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
|
||||||
break;
|
break;
|
||||||
|
case OMPC_acq_rel:
|
||||||
|
Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
|
||||||
|
break;
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
|
Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
|
||||||
break;
|
break;
|
||||||
|
@ -12461,6 +12497,11 @@ OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
|
||||||
return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
|
return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
|
||||||
|
SourceLocation EndLoc) {
|
||||||
|
return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
|
||||||
|
}
|
||||||
|
|
||||||
OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
|
OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
|
||||||
SourceLocation EndLoc) {
|
SourceLocation EndLoc) {
|
||||||
return new (Context) OMPThreadsClause(StartLoc, EndLoc);
|
return new (Context) OMPThreadsClause(StartLoc, EndLoc);
|
||||||
|
@ -12617,6 +12658,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
|
||||||
case OMPC_update:
|
case OMPC_update:
|
||||||
case OMPC_capture:
|
case OMPC_capture:
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
|
case OMPC_acq_rel:
|
||||||
case OMPC_device:
|
case OMPC_device:
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
case OMPC_simd:
|
case OMPC_simd:
|
||||||
|
|
|
@ -8804,6 +8804,13 @@ TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Derived>
|
||||||
|
OMPClause *
|
||||||
|
TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
|
||||||
|
// No need to rebuild this clause, no template-dependent parameters.
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Derived>
|
template <typename Derived>
|
||||||
OMPClause *
|
OMPClause *
|
||||||
TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
|
TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
|
||||||
|
|
|
@ -11666,6 +11666,9 @@ OMPClause *OMPClauseReader::readClause() {
|
||||||
case OMPC_seq_cst:
|
case OMPC_seq_cst:
|
||||||
C = new (Context) OMPSeqCstClause();
|
C = new (Context) OMPSeqCstClause();
|
||||||
break;
|
break;
|
||||||
|
case OMPC_acq_rel:
|
||||||
|
C = new (Context) OMPAcqRelClause();
|
||||||
|
break;
|
||||||
case OMPC_threads:
|
case OMPC_threads:
|
||||||
C = new (Context) OMPThreadsClause();
|
C = new (Context) OMPThreadsClause();
|
||||||
break;
|
break;
|
||||||
|
@ -11928,6 +11931,8 @@ void OMPClauseReader::VisitOMPCaptureClause(OMPCaptureClause *) {}
|
||||||
|
|
||||||
void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
|
void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
|
||||||
|
|
||||||
|
void OMPClauseReader::VisitOMPAcqRelClause(OMPAcqRelClause *) {}
|
||||||
|
|
||||||
void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {}
|
void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {}
|
||||||
|
|
||||||
void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {}
|
void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {}
|
||||||
|
|
|
@ -6147,6 +6147,8 @@ void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {}
|
||||||
|
|
||||||
void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
|
void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
|
||||||
|
|
||||||
|
void OMPClauseWriter::VisitOMPAcqRelClause(OMPAcqRelClause *) {}
|
||||||
|
|
||||||
void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
|
void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
|
||||||
|
|
||||||
void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}
|
void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
|
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s
|
||||||
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
|
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -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
|
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
||||||
|
|
||||||
// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
|
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s | FileCheck %s
|
||||||
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
|
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s
|
||||||
// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
||||||
// expected-no-diagnostics
|
// expected-no-diagnostics
|
||||||
|
|
||||||
#ifndef HEADER
|
#ifndef HEADER
|
||||||
|
@ -44,6 +44,21 @@ T foo(T argc) {
|
||||||
a = b;
|
a = b;
|
||||||
b++;
|
b++;
|
||||||
}
|
}
|
||||||
|
#pragma omp atomic acq_rel
|
||||||
|
a++;
|
||||||
|
#pragma omp atomic read acq_rel
|
||||||
|
a = argc;
|
||||||
|
#pragma omp atomic acq_rel write
|
||||||
|
a = argc + argc;
|
||||||
|
#pragma omp atomic update acq_rel
|
||||||
|
a = a + argc;
|
||||||
|
#pragma omp atomic acq_rel capture
|
||||||
|
a = b++;
|
||||||
|
#pragma omp atomic capture acq_rel
|
||||||
|
{
|
||||||
|
a = b;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +93,21 @@ T foo(T argc) {
|
||||||
// CHECK-NEXT: a = b;
|
// CHECK-NEXT: a = b;
|
||||||
// CHECK-NEXT: b++;
|
// CHECK-NEXT: b++;
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: #pragma omp atomic acq_rel
|
||||||
|
// CHECK-NEXT: a++;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic read acq_rel
|
||||||
|
// CHECK-NEXT: a = argc;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic acq_rel write
|
||||||
|
// CHECK-NEXT: a = argc + argc;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic update acq_rel
|
||||||
|
// CHECK-NEXT: a = a + argc;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic acq_rel capture
|
||||||
|
// CHECK-NEXT: a = b++;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic capture acq_rel
|
||||||
|
// CHECK-NEXT: {
|
||||||
|
// CHECK-NEXT: a = b;
|
||||||
|
// CHECK-NEXT: b++;
|
||||||
|
// CHECK-NEXT: }
|
||||||
// CHECK: int a = int();
|
// CHECK: int a = int();
|
||||||
// CHECK-NEXT: #pragma omp atomic
|
// CHECK-NEXT: #pragma omp atomic
|
||||||
// CHECK-NEXT: a++;
|
// CHECK-NEXT: a++;
|
||||||
|
@ -109,6 +139,21 @@ T foo(T argc) {
|
||||||
// CHECK-NEXT: a = b;
|
// CHECK-NEXT: a = b;
|
||||||
// CHECK-NEXT: b++;
|
// CHECK-NEXT: b++;
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: #pragma omp atomic acq_rel
|
||||||
|
// CHECK-NEXT: a++;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic read acq_rel
|
||||||
|
// CHECK-NEXT: a = argc;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic acq_rel write
|
||||||
|
// CHECK-NEXT: a = argc + argc;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic update acq_rel
|
||||||
|
// CHECK-NEXT: a = a + argc;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic acq_rel capture
|
||||||
|
// CHECK-NEXT: a = b++;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic capture acq_rel
|
||||||
|
// CHECK-NEXT: {
|
||||||
|
// CHECK-NEXT: a = b;
|
||||||
|
// CHECK-NEXT: b++;
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int b = 0;
|
int b = 0;
|
||||||
|
@ -144,6 +189,21 @@ int main(int argc, char **argv) {
|
||||||
a = b;
|
a = b;
|
||||||
b++;
|
b++;
|
||||||
}
|
}
|
||||||
|
#pragma omp atomic acq_rel
|
||||||
|
a++;
|
||||||
|
#pragma omp atomic read acq_rel
|
||||||
|
a = argc;
|
||||||
|
#pragma omp atomic acq_rel write
|
||||||
|
a = argc + argc;
|
||||||
|
#pragma omp atomic update acq_rel
|
||||||
|
a = a + argc;
|
||||||
|
#pragma omp atomic acq_rel capture
|
||||||
|
a = b++;
|
||||||
|
#pragma omp atomic capture acq_rel
|
||||||
|
{
|
||||||
|
a = b;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
// CHECK-NEXT: #pragma omp atomic
|
// CHECK-NEXT: #pragma omp atomic
|
||||||
// CHECK-NEXT: a++;
|
// CHECK-NEXT: a++;
|
||||||
// CHECK-NEXT: #pragma omp atomic read
|
// CHECK-NEXT: #pragma omp atomic read
|
||||||
|
@ -174,6 +234,21 @@ int main(int argc, char **argv) {
|
||||||
// CHECK-NEXT: a = b;
|
// CHECK-NEXT: a = b;
|
||||||
// CHECK-NEXT: b++;
|
// CHECK-NEXT: b++;
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: #pragma omp atomic acq_rel
|
||||||
|
// CHECK-NEXT: a++;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic read acq_rel
|
||||||
|
// CHECK-NEXT: a = argc;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic acq_rel write
|
||||||
|
// CHECK-NEXT: a = argc + argc;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic update acq_rel
|
||||||
|
// CHECK-NEXT: a = a + argc;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic acq_rel capture
|
||||||
|
// CHECK-NEXT: a = b++;
|
||||||
|
// CHECK-NEXT: #pragma omp atomic capture acq_rel
|
||||||
|
// CHECK-NEXT: {
|
||||||
|
// CHECK-NEXT: a = b;
|
||||||
|
// CHECK-NEXT: b++;
|
||||||
|
// CHECK-NEXT: }
|
||||||
return foo(a);
|
return foo(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized
|
// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -ferror-limit 150 %s -Wuninitialized
|
||||||
|
// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -ferror-limit 150 %s -Wuninitialized
|
||||||
|
|
||||||
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized
|
// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 -ferror-limit 150 %s -Wuninitialized
|
||||||
|
// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 -ferror-limit 150 %s -Wuninitialized
|
||||||
|
|
||||||
int foo() {
|
int foo() {
|
||||||
L1:
|
L1:
|
||||||
|
@ -723,6 +725,48 @@ int seq_cst() {
|
||||||
return seq_cst<int>();
|
return seq_cst<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T acq_rel() {
|
||||||
|
T a = 0, b = 0;
|
||||||
|
// omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
|
||||||
|
#pragma omp atomic acq_rel
|
||||||
|
// 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}}
|
||||||
|
;
|
||||||
|
// omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' or 'acq_rel' clause}} omp50-note@+1 2 {{'acq_rel' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
|
||||||
|
#pragma omp atomic acq_rel seq_cst
|
||||||
|
a += b;
|
||||||
|
|
||||||
|
// omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
|
||||||
|
#pragma omp atomic update acq_rel
|
||||||
|
// expected-error@+2 {{the statement for 'atomic update' 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}}
|
||||||
|
;
|
||||||
|
|
||||||
|
return T();
|
||||||
|
}
|
||||||
|
|
||||||
|
int acq_rel() {
|
||||||
|
int a = 0, b = 0;
|
||||||
|
// Test for atomic acq_rel
|
||||||
|
// omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
|
||||||
|
#pragma omp atomic acq_rel
|
||||||
|
// 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}}
|
||||||
|
;
|
||||||
|
// omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' or 'acq_rel' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
|
||||||
|
#pragma omp atomic seq_cst acq_rel
|
||||||
|
a += b;
|
||||||
|
|
||||||
|
// omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
|
||||||
|
#pragma omp atomic update acq_rel
|
||||||
|
// expected-error@+2 {{the statement for 'atomic update' 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}}
|
||||||
|
;
|
||||||
|
|
||||||
|
return acq_rel<int>(); // omp50-note {{in instantiation of function template specialization 'acq_rel<int>' requested here}}
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T mixed() {
|
T mixed() {
|
||||||
T a, b = T();
|
T a, b = T();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
|
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s
|
||||||
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
|
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -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
|
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
||||||
|
|
||||||
// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
|
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s | FileCheck %s
|
||||||
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
|
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s
|
||||||
// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
||||||
// expected-no-diagnostics
|
// expected-no-diagnostics
|
||||||
|
|
||||||
#ifndef HEADER
|
#ifndef HEADER
|
||||||
|
@ -16,25 +16,31 @@ template <class T>
|
||||||
T tmain(T argc) {
|
T tmain(T argc) {
|
||||||
static T a;
|
static T a;
|
||||||
#pragma omp flush
|
#pragma omp flush
|
||||||
|
#pragma omp flush acq_rel
|
||||||
#pragma omp flush(a)
|
#pragma omp flush(a)
|
||||||
return a + argc;
|
return a + argc;
|
||||||
}
|
}
|
||||||
// CHECK: static T a;
|
// CHECK: static T a;
|
||||||
// CHECK-NEXT: #pragma omp flush{{$}}
|
// CHECK-NEXT: #pragma omp flush{{$}}
|
||||||
|
// CHECK-NEXT: #pragma omp flush acq_rel{{$}}
|
||||||
// CHECK-NEXT: #pragma omp flush (a)
|
// CHECK-NEXT: #pragma omp flush (a)
|
||||||
// CHECK: static int a;
|
// CHECK: static int a;
|
||||||
// CHECK-NEXT: #pragma omp flush
|
// CHECK-NEXT: #pragma omp flush
|
||||||
|
// CHECK-NEXT: #pragma omp flush acq_rel{{$}}
|
||||||
// CHECK-NEXT: #pragma omp flush (a)
|
// CHECK-NEXT: #pragma omp flush (a)
|
||||||
// CHECK: static char a;
|
// CHECK: static char a;
|
||||||
// CHECK-NEXT: #pragma omp flush
|
// CHECK-NEXT: #pragma omp flush
|
||||||
|
// CHECK-NEXT: #pragma omp flush acq_rel{{$}}
|
||||||
// CHECK-NEXT: #pragma omp flush (a)
|
// CHECK-NEXT: #pragma omp flush (a)
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
static int a;
|
static int a;
|
||||||
// CHECK: static int a;
|
// CHECK: static int a;
|
||||||
#pragma omp flush
|
#pragma omp flush
|
||||||
|
#pragma omp flush acq_rel
|
||||||
#pragma omp flush(a)
|
#pragma omp flush(a)
|
||||||
// CHECK-NEXT: #pragma omp flush
|
// CHECK-NEXT: #pragma omp flush
|
||||||
|
// CHECK-NEXT: #pragma omp flush acq_rel
|
||||||
// CHECK-NEXT: #pragma omp flush (a)
|
// CHECK-NEXT: #pragma omp flush (a)
|
||||||
return tmain(argc) + tmain(argv[0][0]) + a;
|
return tmain(argc) + tmain(argv[0][0]) + a;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized
|
// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized
|
||||||
|
// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wuninitialized
|
||||||
|
|
||||||
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized
|
// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized
|
||||||
|
// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s -Wuninitialized
|
||||||
|
|
||||||
struct S1 { // expected-note 2 {{declared here}}
|
struct S1 { // expected-note 2 {{declared here}}
|
||||||
int a;
|
int a;
|
||||||
|
@ -132,5 +134,9 @@ label1 : {
|
||||||
#pragma omp flush(argc) flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
|
#pragma omp flush(argc) flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
|
||||||
#pragma omp parallel flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
|
#pragma omp parallel flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
|
||||||
;
|
;
|
||||||
|
#pragma omp flush seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp flush'}}
|
||||||
|
#pragma omp flush acq_rel // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}}
|
||||||
|
#pragma omp flush acq_rel (argc) // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp50-error {{'flush' directive with memory order clause 'acq_rel' cannot have the list}} omp50-note {{memory order clause 'acq_rel' is specified here}}
|
||||||
|
#pragma omp flush(argc) acq_rel // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp50-error {{'flush' directive with memory order clause 'acq_rel' cannot have the list}} omp50-note {{memory order clause 'acq_rel' is specified here}}
|
||||||
return tmain(argc);
|
return tmain(argc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2234,6 +2234,8 @@ void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
|
||||||
|
|
||||||
void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
|
void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
|
||||||
|
|
||||||
|
void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
|
||||||
|
|
||||||
void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
|
void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
|
||||||
|
|
||||||
void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
|
void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
|
||||||
|
|
Loading…
Reference in New Issue