[OPENMP 5.0]Initial support for 'allocator' clause.
Added parsing/sema analysis/serialization/deserialization for the 'allocator' clause of the 'allocate' directive. llvm-svn: 355952
This commit is contained in:
parent
85c2955f45
commit
9cc10fc926
|
@ -396,6 +396,8 @@ public:
|
|||
void VisitOMPAllocateDecl(const OMPAllocateDecl *D) {
|
||||
for (const auto *E : D->varlists())
|
||||
Visit(E);
|
||||
for (const auto *C : D->clauselists())
|
||||
Visit(C);
|
||||
}
|
||||
|
||||
template <typename SpecializationDecl>
|
||||
|
|
|
@ -421,12 +421,21 @@ public:
|
|||
///
|
||||
class OMPAllocateDecl final
|
||||
: public Decl,
|
||||
private llvm::TrailingObjects<OMPAllocateDecl, Expr *> {
|
||||
private llvm::TrailingObjects<OMPAllocateDecl, Expr *, OMPClause *> {
|
||||
friend class ASTDeclReader;
|
||||
friend TrailingObjects;
|
||||
|
||||
/// Number of variable within the allocate directive.
|
||||
unsigned NumVars = 0;
|
||||
/// Number of clauses associated with the allocate directive.
|
||||
unsigned NumClauses = 0;
|
||||
|
||||
size_t numTrailingObjects(OverloadToken<Expr *>) const {
|
||||
return NumVars;
|
||||
}
|
||||
size_t numTrailingObjects(OverloadToken<OMPClause *>) const {
|
||||
return NumClauses;
|
||||
}
|
||||
|
||||
virtual void anchor();
|
||||
|
||||
|
@ -443,19 +452,41 @@ class OMPAllocateDecl final
|
|||
|
||||
void setVars(ArrayRef<Expr *> VL);
|
||||
|
||||
/// Returns an array of immutable clauses associated with this directive.
|
||||
ArrayRef<OMPClause *> getClauses() const {
|
||||
return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
|
||||
}
|
||||
|
||||
/// Returns an array of clauses associated with this directive.
|
||||
MutableArrayRef<OMPClause *> getClauses() {
|
||||
return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
|
||||
NumClauses);
|
||||
}
|
||||
|
||||
/// Sets an array of clauses to this requires declaration
|
||||
void setClauses(ArrayRef<OMPClause *> CL);
|
||||
|
||||
public:
|
||||
static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, ArrayRef<Expr *> VL);
|
||||
SourceLocation L, ArrayRef<Expr *> VL,
|
||||
ArrayRef<OMPClause *> CL);
|
||||
static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID,
|
||||
unsigned N);
|
||||
unsigned NVars, unsigned NClauses);
|
||||
|
||||
typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
|
||||
typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
|
||||
typedef llvm::iterator_range<varlist_iterator> varlist_range;
|
||||
typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
|
||||
using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
|
||||
using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
|
||||
using clauselist_range = llvm::iterator_range<clauselist_iterator>;
|
||||
using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
|
||||
|
||||
|
||||
unsigned varlist_size() const { return NumVars; }
|
||||
bool varlist_empty() const { return NumVars == 0; }
|
||||
unsigned clauselist_size() const { return NumClauses; }
|
||||
bool clauselist_empty() const { return NumClauses == 0; }
|
||||
|
||||
varlist_range varlists() {
|
||||
return varlist_range(varlist_begin(), varlist_end());
|
||||
|
@ -468,6 +499,21 @@ public:
|
|||
varlist_const_iterator varlist_begin() const { return getVars().begin(); }
|
||||
varlist_const_iterator varlist_end() const { return getVars().end(); }
|
||||
|
||||
clauselist_range clauselists() {
|
||||
return clauselist_range(clauselist_begin(), clauselist_end());
|
||||
}
|
||||
clauselist_const_range clauselists() const {
|
||||
return clauselist_const_range(clauselist_begin(), clauselist_end());
|
||||
}
|
||||
clauselist_iterator clauselist_begin() { return getClauses().begin(); }
|
||||
clauselist_iterator clauselist_end() { return getClauses().end(); }
|
||||
clauselist_const_iterator clauselist_begin() const {
|
||||
return getClauses().begin();
|
||||
}
|
||||
clauselist_const_iterator clauselist_end() const {
|
||||
return getClauses().end();
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == OMPAllocate; }
|
||||
};
|
||||
|
|
|
@ -243,6 +243,58 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// This represents 'allocator' clause in the '#pragma omp ...'
|
||||
/// directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp allocate(a) allocator(omp_default_mem_alloc)
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp allocate' has simple 'allocator'
|
||||
/// clause with the allocator 'omp_default_mem_alloc'.
|
||||
class OMPAllocatorClause : public OMPClause {
|
||||
friend class OMPClauseReader;
|
||||
|
||||
/// Location of '('.
|
||||
SourceLocation LParenLoc;
|
||||
|
||||
/// Expression with the allocator.
|
||||
Stmt *Allocator = nullptr;
|
||||
|
||||
/// Set allocator.
|
||||
void setAllocator(Expr *A) { Allocator = A; }
|
||||
|
||||
public:
|
||||
/// Build 'allocator' clause with the given allocator.
|
||||
///
|
||||
/// \param A Allocator.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc),
|
||||
Allocator(A) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
OMPAllocatorClause()
|
||||
: OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {}
|
||||
|
||||
/// Sets the location of '('.
|
||||
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
|
||||
|
||||
/// Returns the location of '('.
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
|
||||
/// Returns allocator.
|
||||
Expr *getAllocator() const { return cast_or_null<Expr>(Allocator); }
|
||||
|
||||
child_range children() { return child_range(&Allocator, &Allocator + 1); }
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_allocator;
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents 'if' clause in the '#pragma omp ...' directive.
|
||||
///
|
||||
/// \code
|
||||
|
|
|
@ -1614,9 +1614,10 @@ DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, {
|
|||
DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
|
||||
|
||||
DEF_TRAVERSE_DECL(OMPAllocateDecl, {
|
||||
for (auto *I : D->varlists()) {
|
||||
for (auto *I : D->varlists())
|
||||
TRY_TO(TraverseStmt(I));
|
||||
}
|
||||
for (auto *C : D->clauselists())
|
||||
TRY_TO(TraverseOMPClause(C));
|
||||
})
|
||||
|
||||
// A helper method for TemplateDecl's children.
|
||||
|
@ -2826,6 +2827,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPAllocatorClause(
|
||||
OMPAllocatorClause *C) {
|
||||
TRY_TO(TraverseStmt(C->getAllocator()));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
|
||||
TRY_TO(VisitOMPClauseWithPreInit(C));
|
||||
|
|
|
@ -3156,6 +3156,7 @@ def OMPAllocateDecl : InheritableAttr {
|
|||
// This attribute has no spellings as it is only ever created implicitly.
|
||||
let Spellings = [];
|
||||
let SemaHandler = 0;
|
||||
let Args = [ExprArgument<"Allocator">];
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
|
|
|
@ -9135,6 +9135,8 @@ 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>">;
|
||||
} // end of OpenMP category
|
||||
|
||||
let CategoryName = "Related Result Type Issue" in {
|
||||
|
|
|
@ -188,6 +188,9 @@
|
|||
#ifndef OPENMP_DECLARE_MAPPER_CLAUSE
|
||||
#define OPENMP_DECLARE_MAPPER_CLAUSE(Name)
|
||||
#endif
|
||||
#ifndef OPENMP_ALLOCATE_CLAUSE
|
||||
# define OPENMP_ALLOCATE_CLAUSE(Name)
|
||||
#endif
|
||||
|
||||
// OpenMP directives.
|
||||
OPENMP_DIRECTIVE(threadprivate)
|
||||
|
@ -247,6 +250,7 @@ OPENMP_DIRECTIVE_EXT(target_teams_distribute_simd, "target teams distribute simd
|
|||
OPENMP_DIRECTIVE(allocate)
|
||||
|
||||
// OpenMP clauses.
|
||||
OPENMP_CLAUSE(allocator, OMPAllocatorClause)
|
||||
OPENMP_CLAUSE(if, OMPIfClause)
|
||||
OPENMP_CLAUSE(final, OMPFinalClause)
|
||||
OPENMP_CLAUSE(num_threads, OMPNumThreadsClause)
|
||||
|
@ -489,6 +493,9 @@ OPENMP_REQUIRES_CLAUSE(reverse_offload)
|
|||
OPENMP_REQUIRES_CLAUSE(dynamic_allocators)
|
||||
OPENMP_REQUIRES_CLAUSE(atomic_default_mem_order)
|
||||
|
||||
// Clauses allowed for OpenMP directive 'allocate'.
|
||||
OPENMP_ALLOCATE_CLAUSE(allocator)
|
||||
|
||||
// Modifiers for 'atomic_default_mem_order' clause.
|
||||
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst)
|
||||
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel)
|
||||
|
@ -910,6 +917,7 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction)
|
|||
// Clauses allowed for OpenMP directive 'declare mapper'.
|
||||
OPENMP_DECLARE_MAPPER_CLAUSE(map)
|
||||
|
||||
#undef OPENMP_ALLOCATE_CLAUSE
|
||||
#undef OPENMP_DECLARE_MAPPER_CLAUSE
|
||||
#undef OPENMP_TASKGROUP_CLAUSE
|
||||
#undef OPENMP_TASKLOOP_SIMD_CLAUSE
|
||||
|
|
|
@ -8781,6 +8781,8 @@ public:
|
|||
//
|
||||
private:
|
||||
void *VarDataSharingAttributesStack;
|
||||
/// omp_allocator_handle_t type.
|
||||
QualType OMPAllocatorHandleT;
|
||||
/// Number of nested '#pragma omp declare target' directives.
|
||||
unsigned DeclareTargetNestingLevel = 0;
|
||||
/// Initialization of data-sharing attributes stack.
|
||||
|
@ -8892,6 +8894,7 @@ public:
|
|||
/// Called on well-formed '#pragma omp allocate'.
|
||||
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc,
|
||||
ArrayRef<Expr *> VarList,
|
||||
ArrayRef<OMPClause *> Clauses,
|
||||
DeclContext *Owner = nullptr);
|
||||
/// Called on well-formed '#pragma omp requires'.
|
||||
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc,
|
||||
|
@ -9247,6 +9250,11 @@ public:
|
|||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// Called on well-formed 'allocator' clause.
|
||||
OMPClause *ActOnOpenMPAllocatorClause(Expr *Allocator,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// Called on well-formed 'if' clause.
|
||||
OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
|
||||
Expr *Condition, SourceLocation StartLoc,
|
||||
|
|
|
@ -59,20 +59,26 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
|
|||
void OMPAllocateDecl::anchor() { }
|
||||
|
||||
OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
ArrayRef<Expr *> VL) {
|
||||
OMPAllocateDecl *D = new (C, DC, additionalSizeToAlloc<Expr *>(VL.size()))
|
||||
SourceLocation L, ArrayRef<Expr *> VL,
|
||||
ArrayRef<OMPClause *> CL) {
|
||||
OMPAllocateDecl *D = new (
|
||||
C, DC, additionalSizeToAlloc<Expr *, OMPClause *>(VL.size(), CL.size()))
|
||||
OMPAllocateDecl(OMPAllocate, DC, L);
|
||||
D->NumVars = VL.size();
|
||||
D->setVars(VL);
|
||||
D->NumClauses = CL.size();
|
||||
D->setClauses(CL);
|
||||
return D;
|
||||
}
|
||||
|
||||
OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, unsigned ID,
|
||||
unsigned N) {
|
||||
OMPAllocateDecl *D = new (C, ID, additionalSizeToAlloc<Expr *>(N))
|
||||
OMPAllocateDecl(OMPAllocate, nullptr, SourceLocation());
|
||||
D->NumVars = N;
|
||||
unsigned NVars,
|
||||
unsigned NClauses) {
|
||||
OMPAllocateDecl *D =
|
||||
new (C, ID, additionalSizeToAlloc<Expr *, OMPClause *>(NVars, NClauses))
|
||||
OMPAllocateDecl(OMPAllocate, nullptr, SourceLocation());
|
||||
D->NumVars = NVars;
|
||||
D->NumClauses = NClauses;
|
||||
return D;
|
||||
}
|
||||
|
||||
|
@ -82,6 +88,13 @@ void OMPAllocateDecl::setVars(ArrayRef<Expr *> VL) {
|
|||
std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
|
||||
}
|
||||
|
||||
void OMPAllocateDecl::setClauses(ArrayRef<OMPClause *> CL) {
|
||||
assert(CL.size() == NumClauses &&
|
||||
"Number of variables is not the same as the preallocated buffer");
|
||||
std::uninitialized_copy(CL.begin(), CL.end(),
|
||||
getTrailingObjects<OMPClause *>());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OMPRequiresDecl Implementation.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -1560,6 +1560,12 @@ void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
|
|||
}
|
||||
Out << ")";
|
||||
}
|
||||
if (!D->clauselist_empty()) {
|
||||
Out << " ";
|
||||
OMPClausePrinter Printer(Out, Policy);
|
||||
for (OMPClause *C : D->clauselists())
|
||||
Printer.Visit(C);
|
||||
}
|
||||
}
|
||||
|
||||
void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
|
||||
|
|
|
@ -73,6 +73,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
|
|||
case OMPC_final:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_private:
|
||||
case OMPC_shared:
|
||||
|
@ -145,6 +146,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
|
|||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_private:
|
||||
case OMPC_shared:
|
||||
|
@ -1086,6 +1088,12 @@ void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
|
|||
OS << ")";
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
|
||||
OS << "allocator(";
|
||||
Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
|
||||
OS << "collapse(";
|
||||
Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
|
||||
|
|
|
@ -457,6 +457,11 @@ void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
|
|||
Profiler->VisitStmt(C->getSimdlen());
|
||||
}
|
||||
|
||||
void OMPClauseProfiler::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
|
||||
if (C->getAllocator())
|
||||
Profiler->VisitStmt(C->getAllocator());
|
||||
}
|
||||
|
||||
void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
|
||||
if (C->getNumForLoops())
|
||||
Profiler->VisitStmt(C->getNumForLoops());
|
||||
|
|
|
@ -155,6 +155,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
|
|||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_private:
|
||||
case OMPC_firstprivate:
|
||||
|
@ -337,6 +338,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
|||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_private:
|
||||
case OMPC_firstprivate:
|
||||
|
@ -805,6 +807,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
|||
#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) \
|
||||
case OMPC_##Name: \
|
||||
return true;
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OMPD_allocate:
|
||||
switch (CKind) {
|
||||
#define OPENMP_ALLOCATE_CLAUSE(Name) \
|
||||
case OMPC_##Name: \
|
||||
return true;
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
default:
|
||||
break;
|
||||
|
@ -814,7 +826,6 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
|||
case OMPD_end_declare_target:
|
||||
case OMPD_unknown:
|
||||
case OMPD_threadprivate:
|
||||
case OMPD_allocate:
|
||||
case OMPD_section:
|
||||
case OMPD_master:
|
||||
case OMPD_taskyield:
|
||||
|
|
|
@ -3948,6 +3948,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
|
|||
case OMPC_in_reduction:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_default:
|
||||
case OMPC_seq_cst:
|
||||
|
|
|
@ -842,7 +842,7 @@ void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
|
|||
/// annot_pragma_openmp_end
|
||||
///
|
||||
/// allocate-directive:
|
||||
/// annot_pragma_openmp 'allocate' simple-variable-list
|
||||
/// annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
|
||||
/// annot_pragma_openmp_end
|
||||
///
|
||||
/// declare-reduction-directive:
|
||||
|
@ -897,16 +897,44 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
|
|||
DeclDirectiveListParserHelper Helper(this, DKind);
|
||||
if (!ParseOpenMPSimpleVarList(DKind, Helper,
|
||||
/*AllowScopeSpecifier=*/true)) {
|
||||
// The last seen token is annot_pragma_openmp_end - need to check for
|
||||
// extra tokens.
|
||||
SmallVector<OMPClause *, 1> Clauses;
|
||||
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
|
||||
<< getOpenMPDirectiveName(DKind);
|
||||
SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
|
||||
OMPC_unknown + 1>
|
||||
FirstClauses(OMPC_unknown + 1);
|
||||
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||
OpenMPClauseKind CKind =
|
||||
Tok.isAnnotation() ? OMPC_unknown
|
||||
: getOpenMPClauseKind(PP.getSpelling(Tok));
|
||||
Actions.StartOpenMPClause(CKind);
|
||||
OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
|
||||
!FirstClauses[CKind].getInt());
|
||||
SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
|
||||
StopBeforeMatch);
|
||||
FirstClauses[CKind].setInt(true);
|
||||
if (Clause != nullptr)
|
||||
Clauses.push_back(Clause);
|
||||
if (Tok.is(tok::annot_pragma_openmp_end)) {
|
||||
Actions.EndOpenMPClause();
|
||||
break;
|
||||
}
|
||||
// Skip ',' if any.
|
||||
if (Tok.is(tok::comma))
|
||||
ConsumeToken();
|
||||
Actions.EndOpenMPClause();
|
||||
}
|
||||
// The last seen token is annot_pragma_openmp_end - need to check for
|
||||
// extra tokens.
|
||||
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
|
||||
<< getOpenMPDirectiveName(DKind);
|
||||
SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
}
|
||||
}
|
||||
// Skip the last annot_pragma_openmp_end.
|
||||
ConsumeAnnotationToken();
|
||||
return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers());
|
||||
return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
|
||||
Clauses);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -925,9 +953,10 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
|
|||
? OMPC_unknown
|
||||
: getOpenMPClauseKind(PP.getSpelling(Tok));
|
||||
Actions.StartOpenMPClause(CKind);
|
||||
OMPClause *Clause =
|
||||
ParseOpenMPClause(OMPD_requires, CKind, !FirstClauses[CKind].getInt());
|
||||
SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
|
||||
!FirstClauses[CKind].getInt());
|
||||
SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
|
||||
StopBeforeMatch);
|
||||
FirstClauses[CKind].setInt(true);
|
||||
if (Clause != nullptr)
|
||||
Clauses.push_back(Clause);
|
||||
|
@ -1214,15 +1243,42 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
|
|||
DeclDirectiveListParserHelper Helper(this, DKind);
|
||||
if (!ParseOpenMPSimpleVarList(DKind, Helper,
|
||||
/*AllowScopeSpecifier=*/false)) {
|
||||
// The last seen token is annot_pragma_openmp_end - need to check for
|
||||
// extra tokens.
|
||||
SmallVector<OMPClause *, 1> Clauses;
|
||||
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
|
||||
<< getOpenMPDirectiveName(DKind);
|
||||
SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
|
||||
OMPC_unknown + 1>
|
||||
FirstClauses(OMPC_unknown + 1);
|
||||
while (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||
OpenMPClauseKind CKind =
|
||||
Tok.isAnnotation() ? OMPC_unknown
|
||||
: getOpenMPClauseKind(PP.getSpelling(Tok));
|
||||
Actions.StartOpenMPClause(CKind);
|
||||
OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
|
||||
!FirstClauses[CKind].getInt());
|
||||
SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
|
||||
StopBeforeMatch);
|
||||
FirstClauses[CKind].setInt(true);
|
||||
if (Clause != nullptr)
|
||||
Clauses.push_back(Clause);
|
||||
if (Tok.is(tok::annot_pragma_openmp_end)) {
|
||||
Actions.EndOpenMPClause();
|
||||
break;
|
||||
}
|
||||
// Skip ',' if any.
|
||||
if (Tok.is(tok::comma))
|
||||
ConsumeToken();
|
||||
Actions.EndOpenMPClause();
|
||||
}
|
||||
// The last seen token is annot_pragma_openmp_end - need to check for
|
||||
// extra tokens.
|
||||
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
|
||||
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
|
||||
<< getOpenMPDirectiveName(DKind);
|
||||
SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
}
|
||||
}
|
||||
DeclGroupPtrTy Res =
|
||||
Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers());
|
||||
DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
|
||||
Loc, Helper.getIdentifiers(), Clauses);
|
||||
Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
|
||||
}
|
||||
SkipUntil(tok::annot_pragma_openmp_end);
|
||||
|
@ -1506,7 +1562,7 @@ bool Parser::ParseOpenMPSimpleVarList(
|
|||
/// thread_limit-clause | priority-clause | grainsize-clause |
|
||||
/// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
|
||||
/// from-clause | is_device_ptr-clause | task_reduction-clause |
|
||||
/// in_reduction-clause
|
||||
/// in_reduction-clause | allocator-clause
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
||||
OpenMPClauseKind CKind, bool FirstClause) {
|
||||
|
@ -1535,6 +1591,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
case OMPC_grainsize:
|
||||
case OMPC_num_tasks:
|
||||
case OMPC_hint:
|
||||
case OMPC_allocator:
|
||||
// OpenMP [2.5, Restrictions]
|
||||
// At most one num_threads clause can appear on the directive.
|
||||
// OpenMP [2.8.1, simd construct, Restrictions]
|
||||
|
@ -1555,6 +1612,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
// At most one grainsize clause can appear on the directive.
|
||||
// OpenMP [2.9.2, taskloop Construct, Restrictions]
|
||||
// At most one num_tasks clause can appear on the directive.
|
||||
// OpenMP [2.11.3, allocate Directive, Restrictions]
|
||||
// At most one allocator clause can appear on the directive.
|
||||
if (!FirstClause) {
|
||||
Diag(Tok, diag::err_omp_more_one_clause)
|
||||
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
|
||||
|
@ -1722,6 +1781,9 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
|
|||
/// hint-clause:
|
||||
/// 'hint' '(' expression ')'
|
||||
///
|
||||
/// allocator-clause:
|
||||
/// 'allocator' '(' expression ')'
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
|
||||
bool ParseOnly) {
|
||||
SourceLocation Loc = ConsumeToken();
|
||||
|
|
|
@ -2194,9 +2194,13 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
|
|||
return D;
|
||||
}
|
||||
|
||||
Sema::DeclGroupPtrTy
|
||||
Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
|
||||
DeclContext *Owner) {
|
||||
Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
|
||||
SourceLocation Loc, ArrayRef<Expr *> VarList,
|
||||
ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
|
||||
assert(Clauses.size() <= 1 && "Expected at most one clause.");
|
||||
Expr *Allocator = nullptr;
|
||||
if (!Clauses.empty())
|
||||
Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
|
||||
SmallVector<Expr *, 8> Vars;
|
||||
for (Expr *RefExpr : VarList) {
|
||||
auto *DE = cast<DeclRefExpr>(RefExpr);
|
||||
|
@ -2213,17 +2217,18 @@ Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
|
|||
continue;
|
||||
|
||||
Vars.push_back(RefExpr);
|
||||
VD->addAttr(
|
||||
OMPAllocateDeclAttr::CreateImplicit(Context, DE->getSourceRange()));
|
||||
Attr *A = OMPAllocateDeclAttr::CreateImplicit(Context, Allocator,
|
||||
DE->getSourceRange());
|
||||
VD->addAttr(A);
|
||||
if (ASTMutationListener *ML = Context.getASTMutationListener())
|
||||
ML->DeclarationMarkedOpenMPAllocate(VD,
|
||||
VD->getAttr<OMPAllocateDeclAttr>());
|
||||
ML->DeclarationMarkedOpenMPAllocate(VD, A);
|
||||
}
|
||||
if (Vars.empty())
|
||||
return nullptr;
|
||||
if (!Owner)
|
||||
Owner = getCurLexicalContext();
|
||||
OMPAllocateDecl *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars);
|
||||
OMPAllocateDecl *D =
|
||||
OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
|
||||
D->setAccess(AS_public);
|
||||
Owner->addDecl(D);
|
||||
return DeclGroupPtrTy::make(DeclGroupRef(D));
|
||||
|
@ -8436,6 +8441,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
|||
case OMPC_simdlen:
|
||||
Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_allocator:
|
||||
Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_collapse:
|
||||
Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
|
@ -9009,6 +9017,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPC_final:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_private:
|
||||
case OMPC_shared:
|
||||
|
@ -9259,6 +9268,43 @@ OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
|
|||
OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// Tries to find omp_allocator_handle_t type.
|
||||
static bool FindOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
|
||||
QualType &OMPAllocatorHandleT) {
|
||||
if (!OMPAllocatorHandleT.isNull())
|
||||
return true;
|
||||
DeclarationName OMPAllocatorHandleTName =
|
||||
&S.getASTContext().Idents.get("omp_allocator_handle_t");
|
||||
auto *TD = dyn_cast_or_null<TypeDecl>(S.LookupSingleName(
|
||||
S.TUScope, OMPAllocatorHandleTName, Loc, Sema::LookupAnyName));
|
||||
if (!TD) {
|
||||
S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
|
||||
return false;
|
||||
}
|
||||
OMPAllocatorHandleT = S.getASTContext().getTypeDeclType(TD);
|
||||
return true;
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc) {
|
||||
// OpenMP [2.11.3, allocate Directive, Description]
|
||||
// allocator is an expression of omp_allocator_handle_t type.
|
||||
if (!FindOMPAllocatorHandleT(*this, A->getExprLoc(), OMPAllocatorHandleT))
|
||||
return nullptr;
|
||||
|
||||
ExprResult Allocator = DefaultLvalueConversion(A);
|
||||
if (Allocator.isInvalid())
|
||||
return nullptr;
|
||||
Allocator = PerformImplicitConversion(Allocator.get(), OMPAllocatorHandleT,
|
||||
Sema::AA_Initializing,
|
||||
/*AllowExplicit=*/true);
|
||||
if (Allocator.isInvalid())
|
||||
return nullptr;
|
||||
return new (Context)
|
||||
OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
|
@ -9326,6 +9372,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
|
|||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_schedule:
|
||||
case OMPC_private:
|
||||
|
@ -9503,6 +9550,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
|
|||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_default:
|
||||
case OMPC_proc_bind:
|
||||
|
@ -9724,6 +9772,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
|
|||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_schedule:
|
||||
case OMPC_private:
|
||||
|
@ -9928,6 +9977,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
|
|||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
case OMPC_simdlen:
|
||||
case OMPC_allocator:
|
||||
case OMPC_collapse:
|
||||
case OMPC_default:
|
||||
case OMPC_proc_bind:
|
||||
|
|
|
@ -2883,9 +2883,20 @@ Decl *TemplateDeclInstantiator::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
|
|||
assert(isa<DeclRefExpr>(Var) && "allocate arg is not a DeclRefExpr");
|
||||
Vars.push_back(Var);
|
||||
}
|
||||
SmallVector<OMPClause *, 4> Clauses;
|
||||
// Copy map clauses from the original mapper.
|
||||
for (OMPClause *C : D->clauselists()) {
|
||||
auto *AC = cast<OMPAllocatorClause>(C);
|
||||
ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs);
|
||||
if (!NewE.isUsable())
|
||||
continue;
|
||||
OMPClause *IC = SemaRef.ActOnOpenMPAllocatorClause(
|
||||
NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());
|
||||
Clauses.push_back(IC);
|
||||
}
|
||||
|
||||
Sema::DeclGroupPtrTy Res =
|
||||
SemaRef.ActOnOpenMPAllocateDirective(D->getLocation(), Vars, Owner);
|
||||
Sema::DeclGroupPtrTy Res = SemaRef.ActOnOpenMPAllocateDirective(
|
||||
D->getLocation(), Vars, Clauses, Owner);
|
||||
if (Res.get().isNull())
|
||||
return nullptr;
|
||||
return Res.get().getSingleDecl();
|
||||
|
|
|
@ -1554,6 +1554,16 @@ public:
|
|||
return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// Build a new OpenMP 'allocator' clause.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new OpenMP clause.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc) {
|
||||
return getSema().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc, EndLoc);
|
||||
}
|
||||
|
||||
/// Build a new OpenMP 'collapse' clause.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new OpenMP clause.
|
||||
|
@ -8343,6 +8353,16 @@ TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
|
|||
E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
OMPClause *
|
||||
TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
|
||||
ExprResult E = getDerived().TransformExpr(C->getAllocator());
|
||||
if (E.isInvalid())
|
||||
return nullptr;
|
||||
return getDerived().RebuildOMPAllocatorClause(
|
||||
E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
OMPClause *
|
||||
TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
|
||||
|
|
|
@ -11704,6 +11704,9 @@ OMPClause *OMPClauseReader::readClause() {
|
|||
case OMPC_simdlen:
|
||||
C = new (Context) OMPSimdlenClause();
|
||||
break;
|
||||
case OMPC_allocator:
|
||||
C = new (Context) OMPAllocatorClause();
|
||||
break;
|
||||
case OMPC_collapse:
|
||||
C = new (Context) OMPCollapseClause();
|
||||
break;
|
||||
|
@ -11929,6 +11932,11 @@ void OMPClauseReader::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
|
|||
C->setLParenLoc(Record.readSourceLocation());
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPAllocatorClause(OMPAllocatorClause *C) {
|
||||
C->setAllocator(Record.readExpr());
|
||||
C->setLParenLoc(Record.readSourceLocation());
|
||||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPCollapseClause(OMPCollapseClause *C) {
|
||||
C->setNumForLoops(Record.readSubExpr());
|
||||
C->setLParenLoc(Record.readSourceLocation());
|
||||
|
|
|
@ -2637,12 +2637,19 @@ void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
|
|||
void ASTDeclReader::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
|
||||
VisitDecl(D);
|
||||
unsigned NumVars = D->varlist_size();
|
||||
unsigned NumClauses = D->clauselist_size();
|
||||
SmallVector<Expr *, 16> Vars;
|
||||
Vars.reserve(NumVars);
|
||||
for (unsigned i = 0; i != NumVars; ++i) {
|
||||
Vars.push_back(Record.readExpr());
|
||||
}
|
||||
D->setVars(Vars);
|
||||
SmallVector<OMPClause *, 8> Clauses;
|
||||
Clauses.reserve(NumClauses);
|
||||
OMPClauseReader ClauseReader(Record);
|
||||
for (unsigned I = 0; I != NumClauses; ++I)
|
||||
Clauses.push_back(ClauseReader.readClause());
|
||||
D->setClauses(Clauses);
|
||||
}
|
||||
|
||||
void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) {
|
||||
|
@ -3878,9 +3885,12 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
|
|||
case DECL_OMP_THREADPRIVATE:
|
||||
D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record.readInt());
|
||||
break;
|
||||
case DECL_OMP_ALLOCATE:
|
||||
D = OMPAllocateDecl::CreateDeserialized(Context, ID, Record.readInt());
|
||||
case DECL_OMP_ALLOCATE: {
|
||||
unsigned NumVars = Record.readInt();
|
||||
unsigned NumClauses = Record.readInt();
|
||||
D = OMPAllocateDecl::CreateDeserialized(Context, ID, NumVars, NumClauses);
|
||||
break;
|
||||
}
|
||||
case DECL_OMP_REQUIRES:
|
||||
D = OMPRequiresDecl::CreateDeserialized(Context, ID, Record.readInt());
|
||||
break;
|
||||
|
@ -4481,8 +4491,8 @@ void ASTDeclReader::UpdateDecl(Decl *D,
|
|||
break;
|
||||
|
||||
case UPD_DECL_MARKED_OPENMP_ALLOCATE:
|
||||
D->addAttr(OMPAllocateDeclAttr::CreateImplicit(Reader.getContext(),
|
||||
ReadSourceRange()));
|
||||
D->addAttr(OMPAllocateDeclAttr::CreateImplicit(
|
||||
Reader.getContext(), Record.readExpr(), ReadSourceRange()));
|
||||
break;
|
||||
|
||||
case UPD_DECL_EXPORTED: {
|
||||
|
|
|
@ -5291,6 +5291,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
|
|||
break;
|
||||
|
||||
case UPD_DECL_MARKED_OPENMP_ALLOCATE:
|
||||
Record.AddStmt(D->getAttr<OMPAllocateDeclAttr>()->getAllocator());
|
||||
Record.AddSourceRange(D->getAttr<OMPAllocateDeclAttr>()->getRange());
|
||||
break;
|
||||
|
||||
|
@ -6534,6 +6535,11 @@ void OMPClauseWriter::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
|
|||
Record.AddSourceLocation(C->getLParenLoc());
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPAllocatorClause(OMPAllocatorClause *C) {
|
||||
Record.AddStmt(C->getAllocator());
|
||||
Record.AddSourceLocation(C->getLParenLoc());
|
||||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
|
||||
Record.AddStmt(C->getNumForLoops());
|
||||
Record.AddSourceLocation(C->getLParenLoc());
|
||||
|
|
|
@ -1747,9 +1747,13 @@ void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
|
|||
|
||||
void ASTDeclWriter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
|
||||
Record.push_back(D->varlist_size());
|
||||
Record.push_back(D->clauselist_size());
|
||||
VisitDecl(D);
|
||||
for (auto *I : D->varlists())
|
||||
Record.AddStmt(I);
|
||||
OMPClauseWriter ClauseWriter(Record);
|
||||
for (OMPClause *C : D->clauselists())
|
||||
ClauseWriter.writeClause(C);
|
||||
Code = serialization::DECL_OMP_ALLOCATE;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin10.6.0 -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
|
||||
// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-linux-gnu -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
|
||||
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-unknown-linux-gnu -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
typedef void **omp_allocator_handle_t;
|
||||
extern const omp_allocator_handle_t omp_default_mem_alloc;
|
||||
extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
|
||||
extern const omp_allocator_handle_t omp_const_mem_alloc;
|
||||
extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
|
||||
extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
|
||||
extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
|
||||
extern const omp_allocator_handle_t omp_pteam_mem_alloc;
|
||||
extern const omp_allocator_handle_t omp_thread_mem_alloc;
|
||||
|
||||
struct St{
|
||||
int a;
|
||||
};
|
||||
|
||||
struct St1{
|
||||
int a;
|
||||
static int b;
|
||||
// CHECK: static int b;
|
||||
#pragma omp allocate(b) allocator(omp_default_mem_alloc)
|
||||
// CHECK-NEXT: #pragma omp allocate(St1::b) allocator(omp_default_mem_alloc){{$}}
|
||||
} d;
|
||||
|
||||
int a, b;
|
||||
// CHECK: int a;
|
||||
// CHECK: int b;
|
||||
#pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
|
||||
#pragma omp allocate(a) allocator(omp_const_mem_alloc)
|
||||
// CHECK-NEXT: #pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
|
||||
// CHECK-NEXT: #pragma omp allocate(a) allocator(omp_const_mem_alloc)
|
||||
#pragma omp allocate(d, b) allocator(omp_high_bw_mem_alloc)
|
||||
// CHECK-NEXT: #pragma omp allocate(d,b) allocator(omp_high_bw_mem_alloc)
|
||||
|
||||
template <class T>
|
||||
struct ST {
|
||||
static T m;
|
||||
#pragma omp allocate(m) allocator(omp_low_lat_mem_alloc)
|
||||
};
|
||||
|
||||
template <class T> T foo() {
|
||||
T v;
|
||||
#pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
|
||||
v = ST<T>::m;
|
||||
return v;
|
||||
}
|
||||
//CHECK: template <class T> T foo() {
|
||||
//CHECK-NEXT: T v;
|
||||
//CHECK-NEXT: #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
|
||||
//CHECK: template<> int foo<int>() {
|
||||
//CHECK-NEXT: int v;
|
||||
//CHECK-NEXT: #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
|
||||
|
||||
namespace ns{
|
||||
int a;
|
||||
}
|
||||
// CHECK: namespace ns {
|
||||
// CHECK-NEXT: int a;
|
||||
// CHECK-NEXT: }
|
||||
#pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc)
|
||||
// CHECK-NEXT: #pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc)
|
||||
|
||||
int main () {
|
||||
static int a;
|
||||
// CHECK: static int a;
|
||||
#pragma omp allocate(a) allocator(omp_thread_mem_alloc)
|
||||
// CHECK-NEXT: #pragma omp allocate(a) allocator(omp_thread_mem_alloc)
|
||||
a=2;
|
||||
return (foo<int>());
|
||||
}
|
||||
|
||||
extern template int ST<int>::m;
|
||||
#endif
|
|
@ -0,0 +1,27 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
|
||||
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp-simd -ferror-limit 100 -o - %s
|
||||
|
||||
struct St{
|
||||
int a;
|
||||
};
|
||||
|
||||
int sss;
|
||||
#pragma omp allocate(sss) allocate // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
|
||||
#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>}}
|
||||
|
||||
typedef void *omp_allocator_handle_t;
|
||||
|
||||
struct St1{
|
||||
int a;
|
||||
static int b;
|
||||
#pragma omp allocate(b) allocator(sss) // expected-error {{initializing 'omp_allocator_handle_t' (aka 'void *') with an expression of incompatible type 'int'}}
|
||||
} d;
|
||||
|
||||
#pragma omp allocate(d) allocator(nullptr)
|
||||
extern void *allocator;
|
||||
#pragma omp allocate(d) allocator(allocator)
|
|
@ -12,14 +12,17 @@
|
|||
#if !defined(PASS1)
|
||||
#define PASS1
|
||||
|
||||
typedef void **omp_allocator_handle_t;
|
||||
extern const omp_allocator_handle_t omp_default_mem_alloc;
|
||||
|
||||
int a;
|
||||
// CHECK: int a;
|
||||
|
||||
#elif !defined(PASS2)
|
||||
#define PASS2
|
||||
|
||||
#pragma omp allocate(a)
|
||||
// CHECK: #pragma omp allocate(a)
|
||||
#pragma omp allocate(a) allocator(omp_default_mem_alloc)
|
||||
// CHECK: #pragma omp allocate(a) allocator(omp_default_mem_alloc)
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -2168,6 +2168,10 @@ void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
|
|||
Visitor->AddStmt(C->getSimdlen());
|
||||
}
|
||||
|
||||
void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
|
||||
Visitor->AddStmt(C->getAllocator());
|
||||
}
|
||||
|
||||
void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
|
||||
Visitor->AddStmt(C->getNumForLoops());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue