diff options
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 57 |
1 files changed, 56 insertions, 1 deletions
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); +} |