forked from OSchip/llvm-project
[OPENMP50]Add basic support for depobj construct.
Added basic parsing/sema/serialization support for depobj directive.
This commit is contained in:
parent
5c83bedeca
commit
c112e941a0
|
@ -2574,7 +2574,11 @@ enum CXCursorKind {
|
|||
*/
|
||||
CXCursor_OMPParallelMasterDirective = 285,
|
||||
|
||||
CXCursor_LastStmt = CXCursor_OMPParallelMasterDirective,
|
||||
/** OpenMP depobj directive.
|
||||
*/
|
||||
CXCursor_OMPDepobjDirective = 286,
|
||||
|
||||
CXCursor_LastStmt = CXCursor_OMPDepobjDirective,
|
||||
|
||||
/**
|
||||
* Cursor that represents the translation unit itself.
|
||||
|
|
|
@ -4108,6 +4108,92 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// This represents implicit clause 'depobj' for the '#pragma omp depobj'
|
||||
/// directive.
|
||||
/// This clause does not exist by itself, it can be only as a part of 'omp
|
||||
/// depobj' directive. This clause is introduced to keep the original structure
|
||||
/// of \a OMPExecutableDirective class and its derivatives and to use the
|
||||
/// existing infrastructure of clauses with the list of variables.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp depobj(a) destroy
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp depobj' has implicit clause 'depobj'
|
||||
/// with the depobj 'a'.
|
||||
class OMPDepobjClause final : public OMPClause {
|
||||
friend class OMPClauseReader;
|
||||
|
||||
/// Location of '('.
|
||||
SourceLocation LParenLoc;
|
||||
|
||||
/// Chunk size.
|
||||
Expr *Depobj = nullptr;
|
||||
|
||||
/// Build clause with number of variables \a N.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_depobj, StartLoc, EndLoc), LParenLoc(LParenLoc) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
///
|
||||
explicit OMPDepobjClause()
|
||||
: OMPClause(OMPC_depobj, SourceLocation(), SourceLocation()) {}
|
||||
|
||||
void setDepobj(Expr *E) { Depobj = E; }
|
||||
|
||||
/// Sets the location of '('.
|
||||
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
|
||||
|
||||
public:
|
||||
/// Creates clause.
|
||||
///
|
||||
/// \param C AST context.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
/// \param Depobj depobj expression associated with the 'depobj' directive.
|
||||
static OMPDepobjClause *Create(const ASTContext &C, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc, Expr *Depobj);
|
||||
|
||||
/// Creates an empty clause.
|
||||
///
|
||||
/// \param C AST context.
|
||||
static OMPDepobjClause *CreateEmpty(const ASTContext &C);
|
||||
|
||||
/// Returns depobj expression associated with the clause.
|
||||
Expr *getDepobj() { return Depobj; }
|
||||
const Expr *getDepobj() const { return Depobj; }
|
||||
|
||||
/// Returns the location of '('.
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
|
||||
child_range children() {
|
||||
return child_range(reinterpret_cast<Stmt **>(&Depobj),
|
||||
reinterpret_cast<Stmt **>(&Depobj) + 1);
|
||||
}
|
||||
|
||||
const_child_range children() const {
|
||||
auto Children = const_cast<OMPDepobjClause *>(this)->children();
|
||||
return const_child_range(Children.begin(), Children.end());
|
||||
}
|
||||
|
||||
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_depobj;
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents implicit clause 'depend' for the '#pragma omp task'
|
||||
/// directive.
|
||||
///
|
||||
|
|
|
@ -2842,6 +2842,9 @@ DEF_TRAVERSE_STMT(OMPCancelDirective,
|
|||
DEF_TRAVERSE_STMT(OMPFlushDirective,
|
||||
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
|
||||
|
||||
DEF_TRAVERSE_STMT(OMPDepobjDirective,
|
||||
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
|
||||
|
||||
DEF_TRAVERSE_STMT(OMPOrderedDirective,
|
||||
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
|
||||
|
||||
|
@ -3347,6 +3350,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPDepobjClause(OMPDepobjClause *C) {
|
||||
TRY_TO(TraverseStmt(C->getDepobj()));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
|
||||
TRY_TO(VisitOMPClauseList(C));
|
||||
|
|
|
@ -2314,6 +2314,64 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// This represents '#pragma omp depobj' directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp depobj(a) depend(in:x,y)
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp depobj' initializes a depobj object
|
||||
/// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
|
||||
class OMPDepobjDirective final : public OMPExecutableDirective {
|
||||
friend class ASTStmtReader;
|
||||
|
||||
/// Build directive with the given start and end location.
|
||||
///
|
||||
/// \param StartLoc Starting location of the directive kind.
|
||||
/// \param EndLoc Ending location of the directive.
|
||||
/// \param NumClauses Number of clauses.
|
||||
///
|
||||
OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc,
|
||||
unsigned NumClauses)
|
||||
: OMPExecutableDirective(this, OMPDepobjDirectiveClass,
|
||||
llvm::omp::OMPD_depobj, StartLoc, EndLoc,
|
||||
NumClauses, 0) {}
|
||||
|
||||
/// Build an empty directive.
|
||||
///
|
||||
/// \param NumClauses Number of clauses.
|
||||
///
|
||||
explicit OMPDepobjDirective(unsigned NumClauses)
|
||||
: OMPExecutableDirective(this, OMPDepobjDirectiveClass,
|
||||
llvm::omp::OMPD_depobj, SourceLocation(),
|
||||
SourceLocation(), NumClauses, 0) {}
|
||||
|
||||
public:
|
||||
/// Creates directive with a list of \a Clauses.
|
||||
///
|
||||
/// \param C AST context.
|
||||
/// \param StartLoc Starting location of the directive kind.
|
||||
/// \param EndLoc Ending Location of the directive.
|
||||
/// \param Clauses List of clauses.
|
||||
///
|
||||
static OMPDepobjDirective *Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
ArrayRef<OMPClause *> Clauses);
|
||||
|
||||
/// Creates an empty directive with the place for \a NumClauses
|
||||
/// clauses.
|
||||
///
|
||||
/// \param C AST context.
|
||||
/// \param NumClauses Number of clauses.
|
||||
///
|
||||
static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
|
||||
unsigned NumClauses, EmptyShell);
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == OMPDepobjDirectiveClass;
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents '#pragma omp ordered' directive.
|
||||
///
|
||||
/// \code
|
||||
|
|
|
@ -10031,8 +10031,14 @@ def note_omp_invalid_subscript_on_this_ptr_map : Note <
|
|||
"expected 'this' subscript expression on map clause to be 'this[0]'">;
|
||||
def err_omp_invalid_map_this_expr : Error <
|
||||
"invalid 'this' expression on 'map' clause">;
|
||||
def err_implied_omp_allocator_handle_t_not_found : Error<
|
||||
"omp_allocator_handle_t type not found; include <omp.h>">;
|
||||
def err_omp_implied_type_not_found : Error<
|
||||
"'%0' type not found; include <omp.h>">;
|
||||
def err_omp_expected_omp_depend_t_lvalue : Error<
|
||||
"expected lvalue expression%select{ of 'omp_depend_t' type, not %1|}0">;
|
||||
def err_omp_depobj_expected : Error<
|
||||
"expected depobj expression">;
|
||||
def err_omp_depobj_single_clause_expected : Error<
|
||||
"exactly one of 'depend', 'destroy', or 'update' clauses is expected">;
|
||||
def err_omp_expected_predefined_allocator : Error<
|
||||
"expected one of the predefined allocators for the variables with the static "
|
||||
"storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', "
|
||||
|
|
|
@ -209,6 +209,9 @@
|
|||
#ifndef OPENMP_FLUSH_CLAUSE
|
||||
#define OPENMP_FLUSH_CLAUSE(Name)
|
||||
#endif
|
||||
#ifndef OPENMP_DEPOBJ_CLAUSE
|
||||
#define OPENMP_DEPOBJ_CLAUSE(Name)
|
||||
#endif
|
||||
|
||||
// OpenMP clauses.
|
||||
OPENMP_CLAUSE(allocator, OMPAllocatorClause)
|
||||
|
@ -272,6 +275,7 @@ OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause)
|
|||
OPENMP_CLAUSE(allocate, OMPAllocateClause)
|
||||
OPENMP_CLAUSE(nontemporal, OMPNontemporalClause)
|
||||
OPENMP_CLAUSE(order, OMPOrderClause)
|
||||
OPENMP_CLAUSE(depobj, OMPDepobjClause)
|
||||
|
||||
// Clauses allowed for OpenMP directive 'parallel'.
|
||||
OPENMP_PARALLEL_CLAUSE(if)
|
||||
|
@ -1078,6 +1082,10 @@ OPENMP_FLUSH_CLAUSE(acq_rel)
|
|||
OPENMP_FLUSH_CLAUSE(acquire)
|
||||
OPENMP_FLUSH_CLAUSE(release)
|
||||
|
||||
// Clauses allowed for OpenMP directive 'depobj'.
|
||||
OPENMP_DEPOBJ_CLAUSE(depend)
|
||||
|
||||
#undef OPENMP_DEPOBJ_CLAUSE
|
||||
#undef OPENMP_FLUSH_CLAUSE
|
||||
#undef OPENMP_ORDER_KIND
|
||||
#undef OPENMP_LASTPRIVATE_KIND
|
||||
|
|
|
@ -232,6 +232,7 @@ def OMPBarrierDirective : StmtNode<OMPExecutableDirective>;
|
|||
def OMPTaskwaitDirective : StmtNode<OMPExecutableDirective>;
|
||||
def OMPTaskgroupDirective : StmtNode<OMPExecutableDirective>;
|
||||
def OMPFlushDirective : StmtNode<OMPExecutableDirective>;
|
||||
def OMPDepobjDirective : StmtNode<OMPExecutableDirective>;
|
||||
def OMPOrderedDirective : StmtNode<OMPExecutableDirective>;
|
||||
def OMPAtomicDirective : StmtNode<OMPExecutableDirective>;
|
||||
def OMPTargetDirective : StmtNode<OMPExecutableDirective>;
|
||||
|
|
|
@ -9994,6 +9994,10 @@ public:
|
|||
StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// Called on well-formed '\#pragma omp depobj'.
|
||||
StmtResult ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// Called on well-formed '\#pragma omp ordered' after parsing of the
|
||||
/// associated statement.
|
||||
StmtResult ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
|
||||
|
@ -10452,6 +10456,10 @@ public:
|
|||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// Called on well-formed 'depobj' pseudo clause.
|
||||
OMPClause *ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// Called on well-formed 'depend' clause.
|
||||
OMPClause *
|
||||
ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
|
||||
|
|
|
@ -1825,6 +1825,7 @@ namespace serialization {
|
|||
STMT_OMP_BARRIER_DIRECTIVE,
|
||||
STMT_OMP_TASKWAIT_DIRECTIVE,
|
||||
STMT_OMP_FLUSH_DIRECTIVE,
|
||||
STMT_OMP_DEPOBJ_DIRECTIVE,
|
||||
STMT_OMP_ORDERED_DIRECTIVE,
|
||||
STMT_OMP_ATOMIC_DIRECTIVE,
|
||||
STMT_OMP_TARGET_DIRECTIVE,
|
||||
|
|
|
@ -111,6 +111,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
|
|||
case OMPC_mergeable:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_read:
|
||||
case OMPC_write:
|
||||
case OMPC_update:
|
||||
|
@ -189,6 +190,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
|
|||
case OMPC_mergeable:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_read:
|
||||
case OMPC_write:
|
||||
case OMPC_update:
|
||||
|
@ -835,6 +837,20 @@ OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
|
|||
return new (Mem) OMPFlushClause(N);
|
||||
}
|
||||
|
||||
OMPDepobjClause *OMPDepobjClause::Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc,
|
||||
Expr *Depobj) {
|
||||
auto *Clause = new (C) OMPDepobjClause(StartLoc, LParenLoc, RParenLoc);
|
||||
Clause->setDepobj(Depobj);
|
||||
return Clause;
|
||||
}
|
||||
|
||||
OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) {
|
||||
return new (C) OMPDepobjClause();
|
||||
}
|
||||
|
||||
OMPDependClause *
|
||||
OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation EndLoc,
|
||||
|
@ -1597,6 +1613,12 @@ void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
|
|||
}
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
|
||||
OS << "(";
|
||||
Node->getDepobj()->printPretty(OS, nullptr, Policy, 0);
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
|
||||
OS << "depend(";
|
||||
OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
|
||||
|
|
|
@ -10,9 +10,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/AST/StmtOpenMP.h"
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/StmtOpenMP.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace llvm::omp;
|
||||
|
@ -759,6 +758,29 @@ OMPFlushDirective *OMPFlushDirective::CreateEmpty(const ASTContext &C,
|
|||
return new (Mem) OMPFlushDirective(NumClauses);
|
||||
}
|
||||
|
||||
OMPDepobjDirective *OMPDepobjDirective::Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
ArrayRef<OMPClause *> Clauses) {
|
||||
unsigned Size =
|
||||
llvm::alignTo(sizeof(OMPDepobjDirective), alignof(OMPClause *));
|
||||
void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size(),
|
||||
alignof(OMPDepobjDirective));
|
||||
auto *Dir = new (Mem) OMPDepobjDirective(StartLoc, EndLoc, Clauses.size());
|
||||
Dir->setClauses(Clauses);
|
||||
return Dir;
|
||||
}
|
||||
|
||||
OMPDepobjDirective *OMPDepobjDirective::CreateEmpty(const ASTContext &C,
|
||||
unsigned NumClauses,
|
||||
EmptyShell) {
|
||||
unsigned Size =
|
||||
llvm::alignTo(sizeof(OMPDepobjDirective), alignof(OMPClause *));
|
||||
void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses,
|
||||
alignof(OMPDepobjDirective));
|
||||
return new (Mem) OMPDepobjDirective(NumClauses);
|
||||
}
|
||||
|
||||
OMPOrderedDirective *OMPOrderedDirective::Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
|
|
|
@ -753,6 +753,11 @@ void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
|
|||
PrintOMPExecutableDirective(Node);
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
|
||||
Indent() << "#pragma omp depobj";
|
||||
PrintOMPExecutableDirective(Node);
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
|
||||
Indent() << "#pragma omp ordered";
|
||||
PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
|
||||
|
|
|
@ -719,6 +719,10 @@ OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
|
|||
void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
}
|
||||
void OMPClauseProfiler::VisitOMPDepobjClause(const OMPDepobjClause *C) {
|
||||
if (const Expr *Depobj = C->getDepobj())
|
||||
Profiler->VisitStmt(Depobj);
|
||||
}
|
||||
void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
}
|
||||
|
@ -885,6 +889,10 @@ void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
|
|||
VisitOMPExecutableDirective(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitOMPDepobjDirective(const OMPDepobjDirective *S) {
|
||||
VisitOMPExecutableDirective(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) {
|
||||
VisitOMPExecutableDirective(S);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,14 @@ OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
|
|||
// clause for 'flush' directive. If the 'flush' clause is explicitly specified
|
||||
// the Parser should generate a warning about extra tokens at the end of the
|
||||
// directive.
|
||||
if (Str == "flush")
|
||||
// 'depobj' clause cannot be specified explicitly, because this is an implicit
|
||||
// clause for 'depobj' directive. If the 'depobj' clause is explicitly
|
||||
// specified the Parser should generate a warning about extra tokens at the
|
||||
// end of the directive.
|
||||
if (llvm::StringSwitch<bool>(Str)
|
||||
.Case("flush", true)
|
||||
.Case("depobj", true)
|
||||
.Default(false))
|
||||
return OMPC_unknown;
|
||||
return llvm::StringSwitch<OpenMPClauseKind>(Str)
|
||||
#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
|
||||
|
@ -166,6 +173,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
|
|||
case OMPC_untied:
|
||||
case OMPC_mergeable:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_read:
|
||||
case OMPC_write:
|
||||
case OMPC_update:
|
||||
|
@ -380,6 +388,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
|||
case OMPC_untied:
|
||||
case OMPC_mergeable:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_read:
|
||||
case OMPC_write:
|
||||
case OMPC_update:
|
||||
|
@ -553,6 +562,20 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case OMPD_depobj:
|
||||
if (OpenMPVersion < 50)
|
||||
return false;
|
||||
switch (CKind) {
|
||||
#define OPENMP_DEPOBJ_CLAUSE(Name) \
|
||||
case OMPC_##Name: \
|
||||
return true;
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
case OMPC_depobj:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OMPD_atomic:
|
||||
if (OpenMPVersion < 50 &&
|
||||
(CKind == OMPC_acq_rel || CKind == OMPC_acquire ||
|
||||
|
@ -1195,6 +1218,7 @@ void clang::getOpenMPCaptureRegions(
|
|||
case OMPD_cancellation_point:
|
||||
case OMPD_cancel:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
|
|
@ -6703,6 +6703,7 @@ emitNumTeamsForTargetDirective(CodeGenFunction &CGF,
|
|||
case OMPD_taskgroup:
|
||||
case OMPD_atomic:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_teams:
|
||||
case OMPD_target_data:
|
||||
case OMPD_target_exit_data:
|
||||
|
@ -7014,6 +7015,7 @@ emitNumThreadsForTargetDirective(CodeGenFunction &CGF,
|
|||
case OMPD_taskgroup:
|
||||
case OMPD_atomic:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_teams:
|
||||
case OMPD_target_data:
|
||||
case OMPD_target_exit_data:
|
||||
|
@ -8798,6 +8800,7 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
|
|||
case OMPD_taskgroup:
|
||||
case OMPD_atomic:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_teams:
|
||||
case OMPD_target_data:
|
||||
case OMPD_target_exit_data:
|
||||
|
@ -9561,6 +9564,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
|
|||
case OMPD_taskgroup:
|
||||
case OMPD_atomic:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_teams:
|
||||
case OMPD_target_data:
|
||||
case OMPD_target_exit_data:
|
||||
|
@ -10201,6 +10205,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall(
|
|||
case OMPD_taskgroup:
|
||||
case OMPD_atomic:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_teams:
|
||||
case OMPD_target_data:
|
||||
case OMPD_distribute:
|
||||
|
|
|
@ -786,6 +786,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx,
|
|||
case OMPD_taskgroup:
|
||||
case OMPD_atomic:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_teams:
|
||||
case OMPD_target_data:
|
||||
case OMPD_target_exit_data:
|
||||
|
@ -862,6 +863,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx,
|
|||
case OMPD_taskgroup:
|
||||
case OMPD_atomic:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_teams:
|
||||
case OMPD_target_data:
|
||||
case OMPD_target_exit_data:
|
||||
|
@ -1031,6 +1033,7 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
|
|||
case OMPD_taskgroup:
|
||||
case OMPD_atomic:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_teams:
|
||||
case OMPD_target_data:
|
||||
case OMPD_target_exit_data:
|
||||
|
@ -1113,6 +1116,7 @@ static bool supportsLightweightRuntime(ASTContext &Ctx,
|
|||
case OMPD_taskgroup:
|
||||
case OMPD_atomic:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_teams:
|
||||
case OMPD_target_data:
|
||||
case OMPD_target_exit_data:
|
||||
|
|
|
@ -247,6 +247,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
|
|||
case Stmt::OMPFlushDirectiveClass:
|
||||
EmitOMPFlushDirective(cast<OMPFlushDirective>(*S));
|
||||
break;
|
||||
case Stmt::OMPDepobjDirectiveClass:
|
||||
EmitOMPDepobjDirective(cast<OMPDepobjDirective>(*S));
|
||||
break;
|
||||
case Stmt::OMPOrderedDirectiveClass:
|
||||
EmitOMPOrderedDirective(cast<OMPOrderedDirective>(*S));
|
||||
break;
|
||||
|
|
|
@ -3800,6 +3800,8 @@ void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
|
|||
S.getBeginLoc(), AO);
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPDepobjDirective(const OMPDepobjDirective &S) {}
|
||||
|
||||
void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
|
||||
const CodeGenLoopTy &CodeGenLoop,
|
||||
Expr *IncExpr) {
|
||||
|
@ -4543,6 +4545,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
|
|||
case OMPC_copyin:
|
||||
case OMPC_copyprivate:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_proc_bind:
|
||||
case OMPC_schedule:
|
||||
case OMPC_ordered:
|
||||
|
|
|
@ -3262,6 +3262,7 @@ public:
|
|||
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
|
||||
void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S);
|
||||
void EmitOMPFlushDirective(const OMPFlushDirective &S);
|
||||
void EmitOMPDepobjDirective(const OMPDepobjDirective &S);
|
||||
void EmitOMPOrderedDirective(const OMPOrderedDirective &S);
|
||||
void EmitOMPAtomicDirective(const OMPAtomicDirective &S);
|
||||
void EmitOMPTargetDirective(const OMPTargetDirective &S);
|
||||
|
|
|
@ -1842,6 +1842,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
|
|||
case OMPD_taskwait:
|
||||
case OMPD_taskgroup:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_for:
|
||||
case OMPD_for_simd:
|
||||
case OMPD_sections:
|
||||
|
@ -2064,6 +2065,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
|
|||
break;
|
||||
}
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_taskyield:
|
||||
case OMPD_barrier:
|
||||
case OMPD_taskwait:
|
||||
|
@ -2123,10 +2125,13 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
|
|||
case OMPD_target_teams_distribute_parallel_for:
|
||||
case OMPD_target_teams_distribute_parallel_for_simd:
|
||||
case OMPD_target_teams_distribute_simd: {
|
||||
// Special processing for flush clause.
|
||||
Token FlushTok;
|
||||
if (DKind == OMPD_flush)
|
||||
FlushTok = Tok;
|
||||
// Special processing for flush and depobj clauses.
|
||||
Token ImplicitTok;
|
||||
bool ImplicitClauseAllowed = false;
|
||||
if (DKind == OMPD_flush || DKind == OMPD_depobj) {
|
||||
ImplicitTok = Tok;
|
||||
ImplicitClauseAllowed = true;
|
||||
}
|
||||
ConsumeToken();
|
||||
// Parse directive name of the 'critical' directive if any.
|
||||
if (DKind == OMPD_critical) {
|
||||
|
@ -2156,22 +2161,32 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
|
|||
Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
|
||||
|
||||
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||
bool FlushHasClause = false;
|
||||
if (DKind == OMPD_flush && Tok.is(tok::l_paren)) {
|
||||
FlushHasClause = true;
|
||||
bool HasImplicitClause = false;
|
||||
if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
|
||||
HasImplicitClause = true;
|
||||
// Push copy of the current token back to stream to properly parse
|
||||
// pseudo-clause OMPFlushClause.
|
||||
// pseudo-clause OMPFlushClause or OMPDepobjClause.
|
||||
PP.EnterToken(Tok, /*IsReinject*/ true);
|
||||
PP.EnterToken(FlushTok, /*IsReinject*/ true);
|
||||
PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
|
||||
ConsumeAnyToken();
|
||||
}
|
||||
OpenMPClauseKind CKind =
|
||||
Tok.isAnnotation()
|
||||
OpenMPClauseKind CKind = Tok.isAnnotation()
|
||||
? OMPC_unknown
|
||||
: FlushHasClause ? OMPC_flush
|
||||
: getOpenMPClauseKind(PP.getSpelling(Tok));
|
||||
if (HasImplicitClause) {
|
||||
assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
|
||||
if (DKind == OMPD_flush) {
|
||||
CKind = OMPC_flush;
|
||||
} else {
|
||||
assert(DKind == OMPD_depobj &&
|
||||
"Expected flush or depobj directives.");
|
||||
CKind = OMPC_depobj;
|
||||
}
|
||||
}
|
||||
// No more implicit clauses allowed.
|
||||
ImplicitClauseAllowed = false;
|
||||
Actions.StartOpenMPClause(CKind);
|
||||
FlushHasClause = false;
|
||||
HasImplicitClause = false;
|
||||
OMPClause *Clause =
|
||||
ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
|
||||
FirstClauses[CKind].setInt(true);
|
||||
|
@ -2324,7 +2339,8 @@ bool Parser::ParseOpenMPSimpleVarList(
|
|||
/// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
|
||||
/// from-clause | is_device_ptr-clause | task_reduction-clause |
|
||||
/// in_reduction-clause | allocator-clause | allocate-clause |
|
||||
/// acq_rel-clause | acquire-clause | release-clause | relaxed-clause
|
||||
/// acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
|
||||
/// depobj-clause
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
||||
OpenMPClauseKind CKind, bool FirstClause) {
|
||||
|
@ -2355,6 +2371,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
case OMPC_num_tasks:
|
||||
case OMPC_hint:
|
||||
case OMPC_allocator:
|
||||
case OMPC_depobj:
|
||||
// OpenMP [2.5, Restrictions]
|
||||
// At most one num_threads clause can appear on the directive.
|
||||
// OpenMP [2.8.1, simd construct, Restrictions]
|
||||
|
|
|
@ -1430,6 +1430,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
|
|||
case Stmt::OMPDistributeParallelForSimdDirectiveClass:
|
||||
case Stmt::OMPDistributeSimdDirectiveClass:
|
||||
case Stmt::OMPFlushDirectiveClass:
|
||||
case Stmt::OMPDepobjDirectiveClass:
|
||||
case Stmt::OMPForDirectiveClass:
|
||||
case Stmt::OMPForSimdDirectiveClass:
|
||||
case Stmt::OMPMasterDirectiveClass:
|
||||
|
|
|
@ -266,6 +266,8 @@ private:
|
|||
SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
|
||||
/// omp_allocator_handle_t type.
|
||||
QualType OMPAllocatorHandleT;
|
||||
/// omp_depend_t type.
|
||||
QualType OMPDependT;
|
||||
/// Expression for the predefined allocators.
|
||||
Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
|
||||
nullptr};
|
||||
|
@ -289,6 +291,10 @@ public:
|
|||
Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
|
||||
return OMPPredefinedAllocators[AllocatorKind];
|
||||
}
|
||||
/// Sets omp_depend_t type.
|
||||
void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
|
||||
/// Gets omp_depend_t type.
|
||||
QualType getOMPDependT() const { return OMPDependT; }
|
||||
|
||||
bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
|
||||
OpenMPClauseKind getClauseParsingMode() const {
|
||||
|
@ -3740,6 +3746,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
|
|||
case OMPD_cancellation_point:
|
||||
case OMPD_cancel:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
@ -4746,6 +4753,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
|||
"No associated statement allowed for 'omp flush' directive");
|
||||
Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
|
||||
break;
|
||||
case OMPD_depobj:
|
||||
assert(AStmt == nullptr &&
|
||||
"No associated statement allowed for 'omp depobj' directive");
|
||||
Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
|
||||
break;
|
||||
case OMPD_ordered:
|
||||
Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
|
||||
EndLoc);
|
||||
|
@ -5032,6 +5044,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
|||
continue;
|
||||
case OMPC_allocator:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_uniform:
|
||||
case OMPC_unknown:
|
||||
|
@ -8597,6 +8610,28 @@ StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
|
|||
return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
|
||||
}
|
||||
|
||||
StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
if (Clauses.empty()) {
|
||||
Diag(StartLoc, diag::err_omp_depobj_expected);
|
||||
return StmtError();
|
||||
} else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
|
||||
Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
|
||||
return StmtError();
|
||||
}
|
||||
// Only depobj expression and another single clause is allowed.
|
||||
if (Clauses.size() > 2) {
|
||||
Diag(Clauses[2]->getBeginLoc(),
|
||||
diag::err_omp_depobj_single_clause_expected);
|
||||
return StmtError();
|
||||
} else if (Clauses.size() < 1) {
|
||||
Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
|
||||
return StmtError();
|
||||
}
|
||||
return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
|
||||
}
|
||||
|
||||
StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
|
||||
Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
|
@ -10890,6 +10925,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
|||
case OMPC_hint:
|
||||
Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_depobj:
|
||||
Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_if:
|
||||
case OMPC_default:
|
||||
case OMPC_proc_bind:
|
||||
|
@ -11071,6 +11109,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_taskwait:
|
||||
case OMPD_cancellation_point:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
@ -11141,6 +11180,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_taskwait:
|
||||
case OMPD_cancellation_point:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
@ -11216,6 +11256,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_taskwait:
|
||||
case OMPD_cancellation_point:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
@ -11288,6 +11329,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_taskwait:
|
||||
case OMPD_cancellation_point:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
@ -11361,6 +11403,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_taskwait:
|
||||
case OMPD_cancellation_point:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
@ -11433,6 +11476,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_taskwait:
|
||||
case OMPD_cancellation_point:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
@ -11504,6 +11548,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_taskwait:
|
||||
case OMPD_cancellation_point:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
@ -11578,6 +11623,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_taskwait:
|
||||
case OMPD_cancellation_point:
|
||||
case OMPD_flush:
|
||||
case OMPD_depobj:
|
||||
case OMPD_declare_reduction:
|
||||
case OMPD_declare_mapper:
|
||||
case OMPD_declare_simd:
|
||||
|
@ -11627,6 +11673,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPC_threadprivate:
|
||||
case OMPC_allocate:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_read:
|
||||
case OMPC_write:
|
||||
case OMPC_update:
|
||||
|
@ -11933,7 +11980,8 @@ static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
|
|||
Stack->setAllocator(AllocatorKind, Res.get());
|
||||
}
|
||||
if (ErrorFound) {
|
||||
S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
|
||||
S.Diag(Loc, diag::err_omp_implied_type_not_found)
|
||||
<< "omp_allocator_handle_t";
|
||||
return false;
|
||||
}
|
||||
OMPAllocatorHandleT.addConst();
|
||||
|
@ -12052,6 +12100,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
|
|||
case OMPC_threadprivate:
|
||||
case OMPC_allocate:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_read:
|
||||
case OMPC_write:
|
||||
case OMPC_update:
|
||||
|
@ -12248,6 +12297,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
|
|||
case OMPC_threadprivate:
|
||||
case OMPC_allocate:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_read:
|
||||
case OMPC_write:
|
||||
case OMPC_update:
|
||||
|
@ -12487,6 +12537,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
|
|||
case OMPC_threadprivate:
|
||||
case OMPC_allocate:
|
||||
case OMPC_flush:
|
||||
case OMPC_depobj:
|
||||
case OMPC_depend:
|
||||
case OMPC_device:
|
||||
case OMPC_map:
|
||||
|
@ -12712,6 +12763,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
|
|||
Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_if:
|
||||
case OMPC_depobj:
|
||||
case OMPC_final:
|
||||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
|
@ -15120,6 +15172,49 @@ OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
|
|||
return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
|
||||
}
|
||||
|
||||
/// Tries to find omp_depend_t. type.
|
||||
static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
|
||||
QualType OMPDependT = Stack->getOMPDependT();
|
||||
if (!OMPDependT.isNull())
|
||||
return true;
|
||||
IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
|
||||
ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
|
||||
if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
|
||||
S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
|
||||
return false;
|
||||
}
|
||||
Stack->setOMPDependT(PT.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc) {
|
||||
if (!Depobj)
|
||||
return nullptr;
|
||||
|
||||
bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
|
||||
|
||||
// OpenMP 5.0, 2.17.10.1 depobj Construct
|
||||
// depobj is an lvalue expression of type omp_depend_t.
|
||||
if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
|
||||
!Depobj->isInstantiationDependent() &&
|
||||
!Depobj->containsUnexpandedParameterPack() &&
|
||||
(OMPDependTFound &&
|
||||
!Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
|
||||
/*CompareUnqualified=*/true))) {
|
||||
Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
|
||||
<< 0 << Depobj->getType() << Depobj->getSourceRange();
|
||||
}
|
||||
|
||||
if (!Depobj->isLValue()) {
|
||||
Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
|
||||
<< 1 << Depobj->getSourceRange();
|
||||
}
|
||||
|
||||
return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
|
||||
}
|
||||
|
||||
OMPClause *
|
||||
Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
|
||||
SourceLocation DepLoc, SourceLocation ColonLoc,
|
||||
|
|
|
@ -1811,6 +1811,17 @@ public:
|
|||
EndLoc);
|
||||
}
|
||||
|
||||
/// Build a new OpenMP 'depobj' pseudo clause.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new OpenMP clause.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc) {
|
||||
return getSema().ActOnOpenMPDepobjClause(Depobj, StartLoc, LParenLoc,
|
||||
EndLoc);
|
||||
}
|
||||
|
||||
/// Build a new OpenMP 'depend' pseudo clause.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new OpenMP clause.
|
||||
|
@ -8263,6 +8274,17 @@ TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
|
|||
return Res;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
StmtResult
|
||||
TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
|
||||
DeclarationNameInfo DirName;
|
||||
getDerived().getSema().StartOpenMPDSABlock(OMPD_depobj, DirName, nullptr,
|
||||
D->getBeginLoc());
|
||||
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
|
||||
getDerived().getSema().EndOpenMPDSABlock(Res.get());
|
||||
return Res;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
StmtResult
|
||||
TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
|
||||
|
@ -9164,6 +9186,16 @@ OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
|
|||
C->getLParenLoc(), C->getEndLoc());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
OMPClause *
|
||||
TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
|
||||
ExprResult E = getDerived().TransformExpr(C->getDepobj());
|
||||
if (E.isInvalid())
|
||||
return nullptr;
|
||||
return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
|
||||
C->getLParenLoc(), C->getEndLoc());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
OMPClause *
|
||||
TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
|
||||
|
|
|
@ -11737,6 +11737,9 @@ OMPClause *OMPClauseReader::readClause() {
|
|||
case OMPC_flush:
|
||||
C = OMPFlushClause::CreateEmpty(Context, Record.readInt());
|
||||
break;
|
||||
case OMPC_depobj:
|
||||
C = OMPDepobjClause::CreateEmpty(Context);
|
||||
break;
|
||||
case OMPC_depend: {
|
||||
unsigned NumVars = Record.readInt();
|
||||
unsigned NumLoops = Record.readInt();
|
||||
|
@ -12249,6 +12252,11 @@ void OMPClauseReader::VisitOMPFlushClause(OMPFlushClause *C) {
|
|||
C->setVarRefs(Vars);
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPDepobjClause(OMPDepobjClause *C) {
|
||||
C->setDepobj(Record.readSubExpr());
|
||||
C->setLParenLoc(Record.readSourceLocation());
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPDependClause(OMPDependClause *C) {
|
||||
C->setLParenLoc(Record.readSourceLocation());
|
||||
C->setDependencyKind(
|
||||
|
|
|
@ -2343,6 +2343,13 @@ void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
|
|||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitOMPDepobjDirective(OMPDepobjDirective *D) {
|
||||
VisitStmt(D);
|
||||
// The NumClauses field was read in ReadStmtFromStream.
|
||||
Record.skipInts(1);
|
||||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
|
||||
VisitStmt(D);
|
||||
// The NumClauses field was read in ReadStmtFromStream.
|
||||
|
@ -3174,6 +3181,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
|||
Context, Record[ASTStmtReader::NumStmtFields], Empty);
|
||||
break;
|
||||
|
||||
case STMT_OMP_DEPOBJ_DIRECTIVE:
|
||||
S = OMPDepobjDirective::CreateEmpty(
|
||||
Context, Record[ASTStmtReader::NumStmtFields], Empty);
|
||||
break;
|
||||
|
||||
case STMT_OMP_ORDERED_DIRECTIVE:
|
||||
S = OMPOrderedDirective::CreateEmpty(
|
||||
Context, Record[ASTStmtReader::NumStmtFields], Empty);
|
||||
|
|
|
@ -6342,6 +6342,11 @@ void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
|
|||
Record.AddStmt(VE);
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPDepobjClause(OMPDepobjClause *C) {
|
||||
Record.AddStmt(C->getDepobj());
|
||||
Record.AddSourceLocation(C->getLParenLoc());
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) {
|
||||
Record.push_back(C->varlist_size());
|
||||
Record.push_back(C->getNumLoops());
|
||||
|
|
|
@ -2314,6 +2314,13 @@ void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
|
|||
Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitOMPDepobjDirective(OMPDepobjDirective *D) {
|
||||
VisitStmt(D);
|
||||
Record.push_back(D->getNumClauses());
|
||||
VisitOMPExecutableDirective(D);
|
||||
Code = serialization::STMT_OMP_DEPOBJ_DIRECTIVE;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
|
||||
VisitStmt(D);
|
||||
Record.push_back(D->getNumClauses());
|
||||
|
|
|
@ -1257,6 +1257,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
|||
case Stmt::OMPTaskwaitDirectiveClass:
|
||||
case Stmt::OMPTaskgroupDirectiveClass:
|
||||
case Stmt::OMPFlushDirectiveClass:
|
||||
case Stmt::OMPDepobjDirectiveClass:
|
||||
case Stmt::OMPOrderedDirectiveClass:
|
||||
case Stmt::OMPAtomicDirectiveClass:
|
||||
case Stmt::OMPTargetDirectiveClass:
|
||||
|
|
|
@ -10,10 +10,10 @@ int sss;
|
|||
#pragma omp allocate(sss) allocat // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
|
||||
#pragma omp allocate(sss) allocate(sss) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp allocate'}}
|
||||
#pragma omp allocate(sss) allocator // expected-error {{expected '(' after 'allocator'}}
|
||||
#pragma omp allocate(sss) allocator(0, // expected-error {{expected ')'}} expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} expected-note {{to match this '('}}
|
||||
#pragma omp allocate(sss) allocator(0,sss // expected-error {{expected ')'}} expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} expected-note {{to match this '('}}
|
||||
#pragma omp allocate(sss) allocator(0,sss) // expected-error {{expected ')'}} expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} expected-note {{to match this '('}}
|
||||
#pragma omp allocate(sss) allocator(sss) // expected-error {{omp_allocator_handle_t type not found; include <omp.h>}}
|
||||
#pragma omp allocate(sss) allocator(0, // expected-error {{expected ')'}} expected-error {{'omp_allocator_handle_t' type not found; include <omp.h>}} expected-note {{to match this '('}}
|
||||
#pragma omp allocate(sss) allocator(0,sss // expected-error {{expected ')'}} expected-error {{'omp_allocator_handle_t' type not found; include <omp.h>}} expected-note {{to match this '('}}
|
||||
#pragma omp allocate(sss) allocator(0,sss) // expected-error {{expected ')'}} expected-error {{'omp_allocator_handle_t' type not found; include <omp.h>}} expected-note {{to match this '('}}
|
||||
#pragma omp allocate(sss) allocator(sss) // expected-error {{'omp_allocator_handle_t' type not found; include <omp.h>}}
|
||||
|
||||
typedef void **omp_allocator_handle_t;
|
||||
extern const omp_allocator_handle_t omp_default_mem_alloc;
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %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 -fopenmp-version=50 -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %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
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
typedef void *omp_depend_t;
|
||||
|
||||
void foo() {}
|
||||
|
||||
template <class T>
|
||||
T tmain(T argc) {
|
||||
static T a;
|
||||
#pragma omp depobj(a) depend(in:argc)
|
||||
return argc;
|
||||
}
|
||||
// CHECK: static T a;
|
||||
// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc){{$}}
|
||||
// CHECK: static void *a;
|
||||
// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc){{$}}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
static omp_depend_t a;
|
||||
omp_depend_t b;
|
||||
// CHECK: static omp_depend_t a;
|
||||
// CHECK-NEXT: omp_depend_t b;
|
||||
#pragma omp depobj(a) depend(out:argc, argv)
|
||||
// CHECK-NEXT: #pragma omp depobj (a) depend(out : argc,argv)
|
||||
(void)tmain(a), tmain(b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,151 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wuninitialized
|
||||
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s -Wuninitialized
|
||||
|
||||
struct S1 { // expected-note 2 {{declared here}}
|
||||
int a;
|
||||
} s;
|
||||
|
||||
#pragma omp depobj(0) depend(in:s) // expected-error {{unexpected OpenMP directive '#pragma omp depobj'}}
|
||||
void foo() {
|
||||
#pragma omp depobj(0) depend(in:s) // expected-error {{'omp_depend_t' type not found; include <omp.h>}} expected-error {{expected lvalue expression}}}
|
||||
}
|
||||
|
||||
typedef void *omp_depend_t;
|
||||
|
||||
template <class T>
|
||||
T tmain(T argc) {
|
||||
omp_depend_t x;
|
||||
#pragma omp depobj() allocate(argc) // expected-error {{expected expression}} expected-error {{expected depobj expression}} expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp depobj'}}
|
||||
;
|
||||
#pragma omp depobj(x) untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp depobj'}}
|
||||
#pragma omp depobj(x) unknown // expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}}
|
||||
if (argc)
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
if (argc) {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
while (argc)
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
while (argc) {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
do
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
while (argc)
|
||||
;
|
||||
do {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
} while (argc);
|
||||
switch (argc)
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
switch (argc)
|
||||
case 1:
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
switch (argc)
|
||||
case 1: {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
switch (argc) {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
case 1:
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
break;
|
||||
default: {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
} break;
|
||||
}
|
||||
for (;;)
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
for (;;) {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
label:
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
label1 : {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
|
||||
#pragma omp depobj // expected-error {{expected depobj expression}}
|
||||
#pragma omp depobj( // expected-error {{expected expression}} expected-error {{expected depobj expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp depobj() // expected-error {{expected expression}} expected-error {{expected depobj expression}}
|
||||
#pragma omp depobj(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}}}
|
||||
#pragma omp depobj(argc, // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}}
|
||||
#pragma omp depobj(argc) // expected-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}}
|
||||
#pragma omp depobj(S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected depobj expression}}
|
||||
#pragma omp depobj(argc) depobj(argc) // expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} expected-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}}}
|
||||
#pragma omp parallel depobj(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
|
||||
;
|
||||
return T();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
omp_depend_t x;
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
;
|
||||
#pragma omp depobj(x) untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp depobj'}}
|
||||
#pragma omp depobj(x) unknown // expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}}
|
||||
if (argc)
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
if (argc) {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
while (argc)
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
while (argc) {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
do
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
while (argc)
|
||||
;
|
||||
do {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
} while (argc);
|
||||
switch (argc)
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
switch (argc)
|
||||
case 1:
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
switch (argc)
|
||||
case 1: {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
switch (argc) {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
case 1:
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
break;
|
||||
default: {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
} break;
|
||||
}
|
||||
for (;;)
|
||||
#pragma omp depobj(x) depend(in:s) // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}}
|
||||
for (;;) {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
label:
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
label1 : {
|
||||
#pragma omp depobj(x) depend(in:s)
|
||||
}
|
||||
|
||||
#pragma omp depobj // expected-error {{expected depobj expression}}
|
||||
#pragma omp depobj( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected depobj expression}}
|
||||
#pragma omp depobj() // expected-error {{expected expression}} expected-error {{expected depobj expression}}
|
||||
#pragma omp depobj(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}}
|
||||
#pragma omp depobj(argc, // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}}
|
||||
#pragma omp depobj(argc) // expected-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}}
|
||||
#pragma omp depobj(S1) // expected-error {{'S1' does not refer to a value}} expected-error {{expected depobj expression}}
|
||||
#pragma omp depobj(argc) depobj(argc) // expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} expected-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}}
|
||||
#pragma omp parallel depobj(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
|
||||
;
|
||||
#pragma omp depobj(x) seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp depobj'}}
|
||||
#pragma omp depobj(x) depend(in: x)
|
||||
#pragma omp depobj(x) (x) depend(in: x) // expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}}
|
||||
#pragma omp depobj(x) depend(in: x) depend(out:x) // expected-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}}
|
||||
#pragma omp depend(out:x) depobj(x) // expected-error {{expected an OpenMP directive}}
|
||||
#pragma omp depobj depend(in:x) (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}}
|
||||
return tmain(argc); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}}
|
||||
}
|
|
@ -142,7 +142,7 @@ label1 : {
|
|||
#pragma omp flush seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp flush'}}
|
||||
#pragma omp flush acq_rel acquire // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} omp50-error {{directive '#pragma omp flush' cannot contain more than one 'acq_rel', 'acquire' or 'release' clause}} omp50-note {{'acq_rel' clause used here}}
|
||||
#pragma omp flush release acquire // omp45-error {{unexpected OpenMP clause 'release' in directive '#pragma omp flush'}} omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} omp50-error {{directive '#pragma omp flush' cannot contain more than one 'acq_rel', 'acquire' or 'release' clause}} omp50-note {{'release' clause used here}}
|
||||
#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 acq_rel (argc) // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -2047,6 +2047,7 @@ public:
|
|||
VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
|
||||
void VisitOMPCancelDirective(const OMPCancelDirective *D);
|
||||
void VisitOMPFlushDirective(const OMPFlushDirective *D);
|
||||
void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
|
||||
void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
|
||||
void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
|
||||
void VisitOMPTargetDirective(const OMPTargetDirective *D);
|
||||
|
@ -2444,6 +2445,9 @@ OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
|
|||
void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
}
|
||||
void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
|
||||
Visitor->AddStmt(C->getDepobj());
|
||||
}
|
||||
void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
|
||||
VisitOMPClauseList(C);
|
||||
}
|
||||
|
@ -2871,6 +2875,10 @@ void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
|
|||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
|
||||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
|
||||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
@ -2883,8 +2891,8 @@ void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
|
|||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
void EnqueueVisitor::VisitOMPTargetDataDirective(const
|
||||
OMPTargetDataDirective *D) {
|
||||
void EnqueueVisitor::VisitOMPTargetDataDirective(
|
||||
const OMPTargetDataDirective *D) {
|
||||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
|
@ -5503,6 +5511,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
|
|||
return cxstring::createRef("OMPTaskgroupDirective");
|
||||
case CXCursor_OMPFlushDirective:
|
||||
return cxstring::createRef("OMPFlushDirective");
|
||||
case CXCursor_OMPDepobjDirective:
|
||||
return cxstring::createRef("OMPDepobjDirective");
|
||||
case CXCursor_OMPOrderedDirective:
|
||||
return cxstring::createRef("OMPOrderedDirective");
|
||||
case CXCursor_OMPAtomicDirective:
|
||||
|
|
|
@ -635,6 +635,9 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
|
|||
case Stmt::OMPFlushDirectiveClass:
|
||||
K = CXCursor_OMPFlushDirective;
|
||||
break;
|
||||
case Stmt::OMPDepobjDirectiveClass:
|
||||
K = CXCursor_OMPDepobjDirective;
|
||||
break;
|
||||
case Stmt::OMPOrderedDirectiveClass:
|
||||
K = CXCursor_OMPOrderedDirective;
|
||||
break;
|
||||
|
|
|
@ -91,6 +91,7 @@ __OMP_DIRECTIVE_EXT(parallel_master_taskloop, "parallel master taskloop")
|
|||
__OMP_DIRECTIVE_EXT(master_taskloop_simd, "master taskloop simd")
|
||||
__OMP_DIRECTIVE_EXT(parallel_master_taskloop_simd,
|
||||
"parallel master taskloop simd")
|
||||
__OMP_DIRECTIVE(depobj)
|
||||
|
||||
// Has to be the last because Clang implicitly expects it to be.
|
||||
__OMP_DIRECTIVE(unknown)
|
||||
|
|
Loading…
Reference in New Issue