forked from OSchip/llvm-project
[OPENMP] 'proc_bind' clause support - Parsing and sema analysis for OpenMP clause 'proc_bind'
llvm-svn: 208060
This commit is contained in:
parent
4cf4e664c2
commit
bcbadb65ab
|
@ -2379,6 +2379,12 @@ bool DataRecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C
|
|||
return true;
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
bool
|
||||
DataRecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *C) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template<typename T>
|
||||
void DataRecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
|
||||
|
|
|
@ -375,6 +375,76 @@ public:
|
|||
StmtRange children() { return StmtRange(); }
|
||||
};
|
||||
|
||||
/// \brief This represents 'proc_bind' clause in the '#pragma omp ...' directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp parallel proc_bind(master)
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp parallel' has simple 'proc_bind'
|
||||
/// clause with kind 'master'.
|
||||
///
|
||||
class OMPProcBindClause : public OMPClause {
|
||||
friend class OMPClauseReader;
|
||||
/// \brief Location of '('.
|
||||
SourceLocation LParenLoc;
|
||||
/// \brief A kind of the 'proc_bind' clause.
|
||||
OpenMPProcBindClauseKind Kind;
|
||||
/// \brief Start location of the kind in source code.
|
||||
SourceLocation KindKwLoc;
|
||||
|
||||
/// \brief Set kind of the clause.
|
||||
///
|
||||
/// \param K Kind of clause.
|
||||
///
|
||||
void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
|
||||
|
||||
/// \brief Set clause kind location.
|
||||
///
|
||||
/// \param KLoc Kind location.
|
||||
///
|
||||
void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
|
||||
|
||||
public:
|
||||
/// \brief Build 'proc_bind' clause with argument \a A ('master', 'close' or
|
||||
/// 'spread').
|
||||
///
|
||||
/// \param A Argument of the clause ('master', 'close' or 'spread').
|
||||
/// \param ALoc Starting location of the argument.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
///
|
||||
OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
|
||||
SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
|
||||
Kind(A), KindKwLoc(ALoc) {}
|
||||
|
||||
/// \brief Build an empty clause.
|
||||
///
|
||||
OMPProcBindClause()
|
||||
: OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()),
|
||||
LParenLoc(SourceLocation()), Kind(OMPC_PROC_BIND_unknown),
|
||||
KindKwLoc(SourceLocation()) {}
|
||||
|
||||
/// \brief Sets the location of '('.
|
||||
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
|
||||
/// \brief Returns the location of '('.
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
|
||||
/// \brief Returns kind of the clause.
|
||||
OpenMPProcBindClauseKind getProcBindKind() const { return Kind; }
|
||||
|
||||
/// \brief Returns location of clause kind.
|
||||
SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_proc_bind;
|
||||
}
|
||||
|
||||
StmtRange children() { return StmtRange(); }
|
||||
};
|
||||
|
||||
/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
|
||||
///
|
||||
/// \code
|
||||
|
|
|
@ -2416,6 +2416,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
|
|||
return true;
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *C) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template<typename T>
|
||||
void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#ifndef OPENMP_DEFAULT_KIND
|
||||
# define OPENMP_DEFAULT_KIND(Name)
|
||||
#endif
|
||||
#ifndef OPENMP_PROC_BIND_KIND
|
||||
# define OPENMP_PROC_BIND_KIND(Name)
|
||||
#endif
|
||||
|
||||
// OpenMP directives.
|
||||
OPENMP_DIRECTIVE(threadprivate)
|
||||
|
@ -44,11 +47,13 @@ OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
|
|||
OPENMP_CLAUSE(shared, OMPSharedClause)
|
||||
OPENMP_CLAUSE(linear, OMPLinearClause)
|
||||
OPENMP_CLAUSE(copyin, OMPCopyinClause)
|
||||
OPENMP_CLAUSE(proc_bind, OMPProcBindClause)
|
||||
|
||||
// Clauses allowed for OpenMP directive 'parallel'.
|
||||
OPENMP_PARALLEL_CLAUSE(if)
|
||||
OPENMP_PARALLEL_CLAUSE(num_threads)
|
||||
OPENMP_PARALLEL_CLAUSE(default)
|
||||
OPENMP_PARALLEL_CLAUSE(proc_bind)
|
||||
OPENMP_PARALLEL_CLAUSE(private)
|
||||
OPENMP_PARALLEL_CLAUSE(firstprivate)
|
||||
OPENMP_PARALLEL_CLAUSE(shared)
|
||||
|
@ -63,6 +68,12 @@ OPENMP_SIMD_CLAUSE(safelen)
|
|||
OPENMP_DEFAULT_KIND(none)
|
||||
OPENMP_DEFAULT_KIND(shared)
|
||||
|
||||
// Static attributes for 'proc_bind' clause.
|
||||
OPENMP_PROC_BIND_KIND(master)
|
||||
OPENMP_PROC_BIND_KIND(close)
|
||||
OPENMP_PROC_BIND_KIND(spread)
|
||||
|
||||
#undef OPENMP_PROC_BIND_KIND
|
||||
#undef OPENMP_DEFAULT_KIND
|
||||
#undef OPENMP_DIRECTIVE
|
||||
#undef OPENMP_CLAUSE
|
||||
|
|
|
@ -47,6 +47,14 @@ enum OpenMPDefaultClauseKind {
|
|||
NUM_OPENMP_DEFAULT_KINDS
|
||||
};
|
||||
|
||||
/// \brief OpenMP attributes for 'proc_bind' clause.
|
||||
enum OpenMPProcBindClauseKind {
|
||||
#define OPENMP_PROC_BIND_KIND(Name) \
|
||||
OMPC_PROC_BIND_##Name,
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
OMPC_PROC_BIND_unknown
|
||||
};
|
||||
|
||||
OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str);
|
||||
const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind);
|
||||
|
||||
|
|
|
@ -7301,6 +7301,12 @@ public:
|
|||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed 'proc_bind' clause.
|
||||
OMPClause *ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
|
||||
SourceLocation KindLoc,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc);
|
||||
|
||||
OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
|
||||
ArrayRef<Expr *> Vars,
|
||||
|
|
|
@ -625,6 +625,12 @@ void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
|
|||
<< ")";
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
|
||||
OS << "proc_bind("
|
||||
<< getOpenMPSimpleClauseTypeName(OMPC_proc_bind, Node->getProcBindKind())
|
||||
<< ")";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
|
||||
for (typename T::varlist_iterator I = Node->varlist_begin(),
|
||||
|
|
|
@ -281,6 +281,8 @@ void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
|
|||
|
||||
void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
|
||||
|
||||
void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
|
||||
|
||||
template<typename T>
|
||||
void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
|
||||
for (auto *I : Node->varlists())
|
||||
|
|
|
@ -75,6 +75,12 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
|
|||
.Case(#Name, OMPC_DEFAULT_##Name)
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
.Default(OMPC_DEFAULT_unknown);
|
||||
case OMPC_proc_bind:
|
||||
return llvm::StringSwitch<OpenMPProcBindClauseKind>(Str)
|
||||
#define OPENMP_PROC_BIND_KIND(Name) \
|
||||
.Case(#Name, OMPC_PROC_BIND_##Name)
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
.Default(OMPC_PROC_BIND_unknown);
|
||||
case OMPC_unknown:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_if:
|
||||
|
@ -103,6 +109,15 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
|||
#include "clang/Basic/OpenMPKinds.def"
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP 'default' clause type");
|
||||
case OMPC_proc_bind:
|
||||
switch (Type) {
|
||||
case OMPC_PROC_BIND_unknown:
|
||||
return "unknown";
|
||||
#define OPENMP_PROC_BIND_KIND(Name) \
|
||||
case OMPC_PROC_BIND_##Name : return #Name;
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
|
||||
case OMPC_unknown:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_if:
|
||||
|
|
|
@ -288,9 +288,12 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
Clause = ParseOpenMPSingleExprClause(CKind);
|
||||
break;
|
||||
case OMPC_default:
|
||||
case OMPC_proc_bind:
|
||||
// OpenMP [2.14.3.1, Restrictions]
|
||||
// Only a single default clause may be specified on a parallel, task or
|
||||
// teams directive.
|
||||
// OpenMP [2.5, parallel Construct, Restrictions]
|
||||
// At most one proc_bind clause can appear on the directive.
|
||||
if (!FirstClause) {
|
||||
Diag(Tok, diag::err_omp_more_one_clause)
|
||||
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind);
|
||||
|
@ -355,11 +358,14 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
|
|||
T.getCloseLocation());
|
||||
}
|
||||
|
||||
/// \brief Parsing of simple OpenMP clauses like 'default'.
|
||||
/// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
|
||||
///
|
||||
/// default-clause:
|
||||
/// 'default' '(' 'none' | 'shared' ')
|
||||
///
|
||||
/// proc_bind-clause:
|
||||
/// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
SourceLocation LOpen = ConsumeToken();
|
||||
|
@ -369,9 +375,9 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
|
|||
getOpenMPClauseName(Kind)))
|
||||
return 0;
|
||||
|
||||
unsigned Type = Tok.isAnnotation() ?
|
||||
unsigned(OMPC_DEFAULT_unknown) :
|
||||
getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
|
||||
unsigned Type =
|
||||
getOpenMPSimpleClauseType(Kind,
|
||||
Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
|
||||
SourceLocation TypeLoc = Tok.getLocation();
|
||||
if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
|
||||
Tok.isNot(tok::annot_pragma_openmp_end))
|
||||
|
|
|
@ -771,6 +771,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
|
|||
Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_default:
|
||||
case OMPC_proc_bind:
|
||||
case OMPC_private:
|
||||
case OMPC_firstprivate:
|
||||
case OMPC_shared:
|
||||
|
@ -924,6 +925,11 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
|
|||
ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
|
||||
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_proc_bind:
|
||||
Res =
|
||||
ActOnOpenMPProcBindClause(static_cast<OpenMPProcBindClauseKind>(Argument),
|
||||
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_if:
|
||||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
|
@ -986,6 +992,37 @@ OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
|
|||
EndLoc);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
|
||||
SourceLocation KindKwLoc,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc) {
|
||||
if (Kind == OMPC_PROC_BIND_unknown) {
|
||||
std::string Values;
|
||||
std::string Sep(", ");
|
||||
for (unsigned i = 0; i < OMPC_PROC_BIND_unknown; ++i) {
|
||||
Values += "'";
|
||||
Values += getOpenMPSimpleClauseTypeName(OMPC_proc_bind, i);
|
||||
Values += "'";
|
||||
switch (i) {
|
||||
case OMPC_PROC_BIND_unknown - 2:
|
||||
Values += " or ";
|
||||
break;
|
||||
case OMPC_PROC_BIND_unknown - 1:
|
||||
break;
|
||||
default:
|
||||
Values += Sep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
|
||||
<< Values << getOpenMPClauseName(OMPC_proc_bind);
|
||||
return 0;
|
||||
}
|
||||
return new (Context) OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc,
|
||||
EndLoc);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
|
||||
ArrayRef<Expr *> VarList,
|
||||
Expr *TailExpr,
|
||||
|
@ -1015,6 +1052,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
|
|||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
case OMPC_default:
|
||||
case OMPC_proc_bind:
|
||||
case OMPC_threadprivate:
|
||||
case OMPC_unknown:
|
||||
case NUM_OPENMP_CLAUSES:
|
||||
|
|
|
@ -1345,6 +1345,19 @@ public:
|
|||
StartLoc, LParenLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new OpenMP 'proc_bind' clause.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new statement.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OMPClause *RebuildOMPProcBindClause(OpenMPProcBindClauseKind Kind,
|
||||
SourceLocation KindKwLoc,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc) {
|
||||
return getSema().ActOnOpenMPProcBindClause(Kind, KindKwLoc,
|
||||
StartLoc, LParenLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new OpenMP 'private' clause.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new statement.
|
||||
|
@ -6394,6 +6407,16 @@ TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
|
|||
C->getLocEnd());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
OMPClause *
|
||||
TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
|
||||
return getDerived().RebuildOMPProcBindClause(C->getProcBindKind(),
|
||||
C->getProcBindKindKwLoc(),
|
||||
C->getLocStart(),
|
||||
C->getLParenLoc(),
|
||||
C->getLocEnd());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
OMPClause *
|
||||
TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
|
||||
|
|
|
@ -1685,6 +1685,9 @@ OMPClause *OMPClauseReader::readClause() {
|
|||
case OMPC_default:
|
||||
C = new (Context) OMPDefaultClause();
|
||||
break;
|
||||
case OMPC_proc_bind:
|
||||
C = new (Context) OMPProcBindClause();
|
||||
break;
|
||||
case OMPC_private:
|
||||
C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]);
|
||||
break;
|
||||
|
@ -1730,6 +1733,13 @@ void OMPClauseReader::VisitOMPDefaultClause(OMPDefaultClause *C) {
|
|||
C->setDefaultKindKwLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPProcBindClause(OMPProcBindClause *C) {
|
||||
C->setProcBindKind(
|
||||
static_cast<OpenMPProcBindClauseKind>(Record[Idx++]));
|
||||
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
C->setProcBindKindKwLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
|
||||
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
unsigned NumVars = C->varlist_size();
|
||||
|
|
|
@ -1696,6 +1696,12 @@ void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
|
|||
Writer->Writer.AddSourceLocation(C->getDefaultKindKwLoc(), Record);
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
|
||||
Record.push_back(C->getProcBindKind());
|
||||
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
||||
Writer->Writer.AddSourceLocation(C->getProcBindKindKwLoc(), Record);
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
|
||||
Record.push_back(C->varlist_size());
|
||||
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
||||
|
|
|
@ -35,9 +35,9 @@ T tmain(T argc, T *argv) {
|
|||
S<T> s;
|
||||
#pragma omp parallel
|
||||
a=2;
|
||||
#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (argc > 0) num_threads(C) copyin(S<T>::TS)
|
||||
#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master)
|
||||
foo();
|
||||
#pragma omp parallel if (C) num_threads(s)
|
||||
#pragma omp parallel if (C) num_threads(s) proc_bind(close)
|
||||
foo();
|
||||
return 0;
|
||||
}
|
||||
|
@ -48,9 +48,9 @@ T tmain(T argc, T *argv) {
|
|||
// CHECK-NEXT: S<int> s;
|
||||
// CHECK-NEXT: #pragma omp parallel
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S<int>::TS)
|
||||
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master)
|
||||
// CHECK-NEXT: foo()
|
||||
// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s)
|
||||
// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close)
|
||||
// CHECK-NEXT: foo()
|
||||
// CHECK: template <typename T = long, int C = 1> long tmain(long argc, long *argv) {
|
||||
// CHECK-NEXT: long b = argc, c, d, e, f, g;
|
||||
|
@ -58,9 +58,9 @@ T tmain(T argc, T *argv) {
|
|||
// CHECK-NEXT: S<long> s;
|
||||
// CHECK-NEXT: #pragma omp parallel
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S<long>::TS)
|
||||
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master)
|
||||
// CHECK-NEXT: foo()
|
||||
// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s)
|
||||
// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close)
|
||||
// CHECK-NEXT: foo()
|
||||
// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
|
||||
// CHECK-NEXT: T b = argc, c, d, e, f, g;
|
||||
|
@ -68,9 +68,9 @@ T tmain(T argc, T *argv) {
|
|||
// CHECK-NEXT: S<T> s;
|
||||
// CHECK-NEXT: #pragma omp parallel
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S<T>::TS)
|
||||
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master)
|
||||
// CHECK-NEXT: foo()
|
||||
// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s)
|
||||
// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close)
|
||||
// CHECK-NEXT: foo()
|
||||
|
||||
enum Enum { };
|
||||
|
@ -86,8 +86,8 @@ int main (int argc, char **argv) {
|
|||
// CHECK-NEXT: #pragma omp parallel
|
||||
a=2;
|
||||
// CHECK-NEXT: a = 2;
|
||||
#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a)
|
||||
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a)
|
||||
#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a) proc_bind(spread)
|
||||
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a) proc_bind(spread)
|
||||
foo();
|
||||
// CHECK-NEXT: foo();
|
||||
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
|
||||
|
||||
void foo();
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
#pragma omp parallel proc_bind // expected-error {{expected '(' after 'proc_bind'}}
|
||||
#pragma omp parallel proc_bind ( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel proc_bind () // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
|
||||
#pragma omp parallel proc_bind (master // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel proc_bind (close), proc_bind(spread) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'proc_bind' clause}}
|
||||
#pragma omp parallel proc_bind (x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
|
||||
foo();
|
||||
|
||||
#pragma omp parallel proc_bind(master)
|
||||
++argc;
|
||||
|
||||
#pragma omp parallel proc_bind(close)
|
||||
#pragma omp parallel proc_bind(spread)
|
||||
++argc;
|
||||
return 0;
|
||||
}
|
|
@ -1937,6 +1937,8 @@ void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
|
|||
|
||||
void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
|
||||
|
||||
void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
|
||||
|
||||
template<typename T>
|
||||
void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
|
||||
for (const auto *I : Node->varlists())
|
||||
|
|
Loading…
Reference in New Issue