summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTTypeTraits.cpp1
-rw-r--r--clang/lib/AST/OpenMPClause.cpp38
-rw-r--r--clang/lib/AST/StmtProfile.cpp5
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp6
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp2
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp31
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp57
-rw-r--r--clang/lib/Sema/TreeTransform.h36
-rw-r--r--clang/lib/Serialization/ASTReader.cpp15
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp9
10 files changed, 189 insertions, 11 deletions
diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp
index dae9ab3a289..ba1581bd3f6 100644
--- a/clang/lib/AST/ASTTypeTraits.cpp
+++ b/clang/lib/AST/ASTTypeTraits.cpp
@@ -113,7 +113,6 @@ ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) {
#define OPENMP_CLAUSE(Name, Class) \
case OMPC_##Name: return ASTNodeKind(NKI_##Class);
#include "clang/Basic/OpenMPKinds.def"
- case OMPC_allocate:
case OMPC_threadprivate:
case OMPC_uniform:
case OMPC_unknown:
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 5ee10fb2a11..5bd4ad81bf8 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -74,6 +74,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_safelen:
case OMPC_simdlen:
case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_shared:
@@ -85,7 +86,6 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_untied:
case OMPC_mergeable:
case OMPC_threadprivate:
- case OMPC_allocate:
case OMPC_flush:
case OMPC_read:
case OMPC_write:
@@ -147,6 +147,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_safelen:
case OMPC_simdlen:
case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_shared:
@@ -158,7 +159,6 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_untied:
case OMPC_mergeable:
case OMPC_threadprivate:
- case OMPC_allocate:
case OMPC_flush:
case OMPC_read:
case OMPC_write:
@@ -701,6 +701,25 @@ OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
return new (Mem) OMPInReductionClause(N);
}
+OMPAllocateClause *
+OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, Expr *Allocator,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ // Allocate space for private variables and initializer expressions.
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
+ auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
+ ColonLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
+ return new (Mem) OMPAllocateClause(N);
+}
+
OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -1264,6 +1283,21 @@ void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
}
}
+void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
+ if (Node->varlist_empty())
+ return;
+ OS << "allocate";
+ if (Expr *Allocator = Node->getAllocator()) {
+ OS << "(";
+ Allocator->printPretty(OS, nullptr, Policy, 0);
+ OS << ":";
+ VisitOMPClauseList(Node, ' ');
+ } else {
+ VisitOMPClauseList(Node, '(');
+ }
+ OS << ")";
+}
+
void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
if (!Node->varlist_empty()) {
OS << "private";
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 53655a18f91..da80322a707 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -716,6 +716,11 @@ void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) {
void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseProfiler::VisitOMPAllocateClause(const OMPAllocateClause *C) {
+ if (Expr *Allocator = C->getAllocator())
+ Profiler->VisitStmt(Allocator);
+ VisitOMPClauseList(C);
+}
void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
VistOMPClauseWithPreInit(C);
if (C->getNumTeams())
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index e4e8adda93b..82e193efef3 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -71,8 +71,6 @@ const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) {
return "uniform";
case OMPC_threadprivate:
return "threadprivate or thread local";
- case OMPC_allocate:
- return "allocate";
}
llvm_unreachable("Invalid OpenMP clause kind");
}
@@ -149,13 +147,13 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
.Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown);
case OMPC_unknown:
case OMPC_threadprivate:
- case OMPC_allocate:
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_simdlen:
case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_firstprivate:
@@ -332,13 +330,13 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type");
case OMPC_unknown:
case OMPC_threadprivate:
- case OMPC_allocate:
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_simdlen:
case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_firstprivate:
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 107825bd936..e739a117bd8 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -3950,6 +3950,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_safelen:
case OMPC_simdlen:
case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_default:
case OMPC_seq_cst:
@@ -3965,7 +3966,6 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_nowait:
case OMPC_untied:
case OMPC_threadprivate:
- case OMPC_allocate:
case OMPC_depend:
case OMPC_mergeable:
case OMPC_device:
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 572863c164f..34798ea39c7 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -1562,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 | allocator-clause
+/// in_reduction-clause | allocator-clause | allocate-clause
///
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind, bool FirstClause) {
@@ -1708,6 +1708,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_allocate:
Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
break;
case OMPC_unknown:
@@ -1716,7 +1717,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
break;
case OMPC_threadprivate:
- case OMPC_allocate:
case OMPC_uniform:
if (!WrongDirective)
Diag(Tok, diag::err_omp_unexpected_clause)
@@ -2306,6 +2306,31 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
ConsumeToken();
}
}
+ } else if (Kind == OMPC_allocate) {
+ // Handle optional allocator expression followed by colon delimiter.
+ ColonProtectionRAIIObject ColonRAII(*this);
+ TentativeParsingAction TPA(*this);
+ ExprResult Tail =
+ Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+ Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
+ /*DiscardedValue=*/false);
+ if (Tail.isUsable()) {
+ if (Tok.is(tok::colon)) {
+ Data.TailExpr = Tail.get();
+ Data.ColonLoc = ConsumeToken();
+ TPA.Commit();
+ } else {
+ // colon not found, no allocator specified, parse only list of
+ // variables.
+ TPA.Revert();
+ }
+ } else {
+ // Parsing was unsuccessfull, revert and skip to the end of clause or
+ // directive.
+ TPA.Revert();
+ SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ }
}
bool IsComma =
@@ -2410,6 +2435,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
/// 'use_device_ptr' '(' list ')'
/// is_device_ptr-clause:
/// 'is_device_ptr' '(' list ')'
+/// allocate-clause:
+/// 'allocate' '(' [ allocator ':' ] list ')'
///
/// For 'linear' clause linear-list may have the following forms:
/// list
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index dbccb69aad7..150b21a8c92 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -10152,6 +10152,10 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
case OMPC_is_device_ptr:
Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
break;
+ case OMPC_allocate:
+ Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
+ ColonLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -10167,7 +10171,6 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
case OMPC_untied:
case OMPC_mergeable:
case OMPC_threadprivate:
- case OMPC_allocate:
case OMPC_read:
case OMPC_write:
case OMPC_update:
@@ -14700,3 +14703,55 @@ OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
MVLI.VarBaseDeclarations,
MVLI.VarComponents);
}
+
+OMPClause *Sema::ActOnOpenMPAllocateClause(
+ Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
+ if (Allocator) {
+ // OpenMP [2.11.4 allocate Clause, Description]
+ // allocator is an expression of omp_allocator_handle_t type.
+ if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
+ return nullptr;
+
+ ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
+ if (AllocatorRes.isInvalid())
+ return nullptr;
+ AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
+ DSAStack->getOMPAllocatorHandleT(),
+ Sema::AA_Initializing,
+ /*AllowExplicit=*/true);
+ if (AllocatorRes.isInvalid())
+ return nullptr;
+ Allocator = AllocatorRes.get();
+ }
+ // Analyze and build list of variables.
+ SmallVector<Expr *, 8> Vars;
+ for (Expr *RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP private clause.");
+ SourceLocation ELoc;
+ SourceRange ERange;
+ Expr *SimpleRefExpr = RefExpr;
+ auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
+ if (Res.second) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ }
+ ValueDecl *D = Res.first;
+ if (!D)
+ continue;
+
+ auto *VD = dyn_cast<VarDecl>(D);
+ DeclRefExpr *Ref = nullptr;
+ if (!VD && !CurContext->isDependentContext())
+ Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
+ Vars.push_back((VD || CurContext->isDependentContext())
+ ? RefExpr->IgnoreParens()
+ : Ref);
+ }
+
+ if (Vars.empty())
+ return nullptr;
+
+ return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
+ ColonLoc, EndLoc, Vars);
+}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 93c5bdfed4c..a8ea6b01d1c 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1827,6 +1827,19 @@ public:
VarList, Locs, UnresolvedMappers);
}
+ /// Build a new OpenMP 'allocate' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPAllocateClause(Allocate, VarList, StartLoc,
+ LParenLoc, ColonLoc, EndLoc);
+ }
+
/// Build a new OpenMP 'num_teams' clause.
///
/// By default, performs semantic analysis to build the new statement.
@@ -8908,6 +8921,29 @@ OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
template <typename Derived>
OMPClause *
+TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
+ Expr *Allocator = C->getAllocator();
+ if (Allocator) {
+ ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
+ if (AllocatorRes.isInvalid())
+ return nullptr;
+ Allocator = AllocatorRes.get();
+ }
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return nullptr;
+ Vars.push_back(EVar.get());
+ }
+ return getDerived().RebuildOMPAllocateClause(
+ Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
+ C->getEndLoc());
+}
+
+template <typename Derived>
+OMPClause *
TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
ExprResult E = getDerived().TransformExpr(C->getNumTeams());
if (E.isInvalid())
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 5ca5e8de556..d381f9e9bd3 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11884,6 +11884,9 @@ OMPClause *OMPClauseReader::readClause() {
C = OMPIsDevicePtrClause::CreateEmpty(Context, Sizes);
break;
}
+ case OMPC_allocate:
+ C = OMPAllocateClause::CreateEmpty(Context, Record.readInt());
+ break;
}
Visit(C);
C->setLocStart(Record.readSourceLocation());
@@ -12379,6 +12382,18 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
C->setComponents(Components, ListSizes);
}
+void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) {
+ C->setLParenLoc(Record.readSourceLocation());
+ C->setColonLoc(Record.readSourceLocation());
+ C->setAllocator(Record.readSubExpr());
+ unsigned NumVars = C->varlist_size();
+ SmallVector<Expr *, 16> Vars;
+ Vars.reserve(NumVars);
+ for (unsigned i = 0; i != NumVars; ++i)
+ Vars.push_back(Record.readSubExpr());
+ C->setVarRefs(Vars);
+}
+
void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
VisitOMPClauseWithPreInit(C);
C->setNumTeams(Record.readSubExpr());
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index c593dd98dba..3609e589193 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6831,6 +6831,15 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
}
}
+void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) {
+ Record.push_back(C->varlist_size());
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getColonLoc());
+ Record.AddStmt(C->getAllocator());
+ for (auto *VE : C->varlists())
+ Record.AddStmt(VE);
+}
+
void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
VisitOMPClauseWithPreInit(C);
Record.AddStmt(C->getNumTeams());
OpenPOWER on IntegriCloud