diff options
Diffstat (limited to 'clang/lib')
22 files changed, 273 insertions, 29 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 41efa951cb4..dee12a5e411 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -9798,12 +9798,12 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { return false; } else if (isa<PragmaCommentDecl>(D)) return true; - else if (isa<OMPThreadPrivateDecl>(D)) - return true; else if (isa<PragmaDetectMismatchDecl>(D)) return true; else if (isa<OMPThreadPrivateDecl>(D)) return !D->getDeclContext()->isDependentContext(); + else if (isa<OMPAllocateDecl>(D)) + return !D->getDeclContext()->isDependentContext(); else if (isa<OMPDeclareReductionDecl>(D)) return !D->getDeclContext()->isDependentContext(); else if (isa<ImportDecl>(D)) diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index a44c8398158..e1b5161b027 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -812,6 +812,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCCategoryImpl: case Import: case OMPThreadPrivate: + case OMPAllocate: case OMPRequires: case OMPCapturedExpr: case Empty: diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp index 39cb46705e5..f50775bced2 100644 --- a/clang/lib/AST/DeclOpenMP.cpp +++ b/clang/lib/AST/DeclOpenMP.cpp @@ -53,6 +53,36 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) { } //===----------------------------------------------------------------------===// +// OMPAllocateDecl Implementation. +//===----------------------------------------------------------------------===// + +void OMPAllocateDecl::anchor() { } + +OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + ArrayRef<Expr *> VL) { + OMPAllocateDecl *D = new (C, DC, additionalSizeToAlloc<Expr *>(VL.size())) + OMPAllocateDecl(OMPAllocate, DC, L); + D->NumVars = VL.size(); + D->setVars(VL); + 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; + return D; +} + +void OMPAllocateDecl::setVars(ArrayRef<Expr *> VL) { + assert(VL.size() == NumVars && + "Number of variables is not the same as the preallocated buffer"); + std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>()); +} + +//===----------------------------------------------------------------------===// // OMPRequiresDecl Implementation. //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 46069898cc0..d023a034e51 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -99,6 +99,7 @@ namespace { void VisitUsingDecl(UsingDecl *D); void VisitUsingShadowDecl(UsingShadowDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + void VisitOMPAllocateDecl(OMPAllocateDecl *D); void VisitOMPRequiresDecl(OMPRequiresDecl *D); void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D); @@ -424,7 +425,8 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { // FIXME: Need to be able to tell the DeclPrinter when const char *Terminator = nullptr; if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) || - isa<OMPDeclareMapperDecl>(*D) || isa<OMPRequiresDecl>(*D)) + isa<OMPDeclareMapperDecl>(*D) || isa<OMPRequiresDecl>(*D) || + isa<OMPAllocateDecl>(*D)) Terminator = nullptr; else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody()) Terminator = nullptr; @@ -1546,6 +1548,20 @@ void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { } } +void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) { + Out << "#pragma omp allocate"; + if (!D->varlist_empty()) { + for (OMPAllocateDecl::varlist_iterator I = D->varlist_begin(), + E = D->varlist_end(); + I != E; ++I) { + Out << (I == D->varlist_begin() ? '(' : ','); + NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl(); + ND->printQualifiedName(Out); + } + Out << ")"; + } +} + void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) { Out << "#pragma omp requires "; if (!D->clauselist_empty()) { diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index a50e2de7f51..4016dd0f061 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -84,6 +84,7 @@ 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: @@ -155,6 +156,7 @@ 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: diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 493ac7b2c67..969828705f2 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -71,6 +71,8 @@ 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"); } @@ -147,6 +149,7 @@ 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: @@ -328,6 +331,7 @@ 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: @@ -810,6 +814,7 @@ 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: @@ -1033,6 +1038,7 @@ void clang::getOpenMPCaptureRegions( CaptureRegions.push_back(OMPD_unknown); break; case OMPD_threadprivate: + case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index a008ad022bd..4acfb15c07f 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -103,6 +103,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::Label: // __label__ x; case Decl::Import: case Decl::OMPThreadPrivate: + case Decl::OMPAllocate: case Decl::OMPCapturedExpr: case Decl::OMPRequires: case Decl::Empty: diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 64fdefd9a6f..0beb134b66a 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -8215,6 +8215,7 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) { case OMPD_cancellation_point: case OMPD_ordered: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_task: case OMPD_simd: case OMPD_sections: @@ -8638,6 +8639,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S, case OMPD_cancellation_point: case OMPD_ordered: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_task: case OMPD_simd: case OMPD_sections: @@ -9156,6 +9158,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall( case OMPD_cancellation_point: case OMPD_ordered: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_task: case OMPD_simd: case OMPD_sections: diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index 534f91cd355..5eaa0f02adc 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -743,7 +743,7 @@ static const Stmt *getSingleCompoundChild(ASTContext &Ctx, const Stmt *Body) { isa<PragmaDetectMismatchDecl>(D) || isa<UsingDecl>(D) || isa<UsingDirectiveDecl>(D) || isa<OMPDeclareReductionDecl>(D) || - isa<OMPThreadPrivateDecl>(D)) + isa<OMPThreadPrivateDecl>(D) || isa<OMPAllocateDecl>(D)) return true; const auto *VD = dyn_cast<VarDecl>(D); if (!VD) @@ -835,6 +835,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx, case OMPD_cancellation_point: case OMPD_ordered: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_task: case OMPD_simd: case OMPD_sections: @@ -904,6 +905,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx, case OMPD_cancellation_point: case OMPD_ordered: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_task: case OMPD_simd: case OMPD_sections: @@ -1055,6 +1057,7 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx, case OMPD_cancellation_point: case OMPD_ordered: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_task: case OMPD_simd: case OMPD_sections: @@ -1129,6 +1132,7 @@ static bool supportsLightweightRuntime(ASTContext &Ctx, case OMPD_cancellation_point: case OMPD_ordered: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_task: case OMPD_simd: case OMPD_sections: diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 020f0b22483..68272224a05 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -3963,6 +3963,7 @@ 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/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 13fa3e780fd..7abffa339e2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5062,6 +5062,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { EmitOMPThreadPrivateDecl(cast<OMPThreadPrivateDecl>(D)); break; + case Decl::OMPAllocate: + break; + case Decl::OMPDeclareReduction: EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(D)); break; diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index baa7f50ba8d..ed7028769d3 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -103,6 +103,7 @@ public: const ObjCInterfaceDecl *IFD) override; void DeclarationMarkedUsed(const Decl *D) override; void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; + void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) override; void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, const Attr *Attr) override; void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; @@ -208,6 +209,11 @@ void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate( for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D); } +void MultiplexASTMutationListener::DeclarationMarkedOpenMPAllocate( + const Decl *D, const Attr *A) { + for (ASTMutationListener *L : Listeners) + L->DeclarationMarkedOpenMPAllocate(D, A); +} void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget( const Decl *D, const Attr *Attr) { for (auto *L : Listeners) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 84d79d9a473..0cca269dcb1 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1734,7 +1734,8 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context, /// [C++11] attribute-specifier-seq decl-specifier-seq[opt] /// init-declarator-list ';' ///[C90/C++]init-declarator-list ';' [TODO] -/// [OMP] threadprivate-directive [TODO] +/// [OMP] threadprivate-directive +/// [OMP] allocate-directive [TODO] /// /// for-range-declaration: [C++11 6.5p1: stmt.ranged] /// attribute-specifier-seq[opt] type-specifier-seq declarator diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 274073041c7..fa418961b29 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -44,15 +44,17 @@ enum OpenMPDirectiveKindEx { OMPD_mapper, }; -class ThreadprivateListParserHelper final { +class DeclDirectiveListParserHelper final { SmallVector<Expr *, 4> Identifiers; Parser *P; + OpenMPDirectiveKind Kind; public: - ThreadprivateListParserHelper(Parser *P) : P(P) {} + DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind) + : P(P), Kind(Kind) {} void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) { - ExprResult Res = - P->getActions().ActOnOpenMPIdExpression(P->getCurScope(), SS, NameInfo); + ExprResult Res = P->getActions().ActOnOpenMPIdExpression( + P->getCurScope(), SS, NameInfo, Kind); if (Res.isUsable()) Identifiers.push_back(Res.get()); } @@ -839,6 +841,10 @@ void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind, /// annot_pragma_openmp 'threadprivate' simple-variable-list /// annot_pragma_openmp_end /// +/// allocate-directive: +/// annot_pragma_openmp 'allocate' simple-variable-list +/// annot_pragma_openmp_end +/// /// declare-reduction-directive: /// annot_pragma_openmp 'declare' 'reduction' [...] /// annot_pragma_openmp_end @@ -869,13 +875,14 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( switch (DKind) { case OMPD_threadprivate: { ConsumeToken(); - ThreadprivateListParserHelper Helper(this); - if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) { + 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. if (Tok.isNot(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::warn_omp_extra_tokens_at_eol) - << getOpenMPDirectiveName(OMPD_threadprivate); + << getOpenMPDirectiveName(DKind); SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); } // Skip the last annot_pragma_openmp_end. @@ -885,6 +892,24 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( } break; } + case OMPD_allocate: { + ConsumeToken(); + 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. + 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()); + } + break; + } case OMPD_requires: { SourceLocation StartLoc = ConsumeToken(); SmallVector<OMPClause *, 5> Clauses; @@ -1098,6 +1123,10 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( /// annot_pragma_openmp 'threadprivate' simple-variable-list /// annot_pragma_openmp_end /// +/// allocate-directive: +/// annot_pragma_openmp 'allocate' simple-variable-list +/// annot_pragma_openmp_end +/// /// declare-reduction-directive: /// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':' /// <type> {',' <type>} ':' <expression> ')' ['initializer' '(' @@ -1157,13 +1186,14 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { << getOpenMPDirectiveName(DKind) << 0; } ConsumeToken(); - ThreadprivateListParserHelper Helper(this); - if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) { + 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. if (Tok.isNot(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::warn_omp_extra_tokens_at_eol) - << getOpenMPDirectiveName(OMPD_threadprivate); + << getOpenMPDirectiveName(DKind); SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); } DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective( @@ -1173,6 +1203,31 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { SkipUntil(tok::annot_pragma_openmp_end); break; } + case OMPD_allocate: { + // FIXME: Should this be permitted in C++? + if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) == + ParsedStmtContext()) { + Diag(Tok, diag::err_omp_immediate_directive) + << getOpenMPDirectiveName(DKind) << 0; + } + ConsumeToken(); + 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. + 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()); + Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); + } + SkipUntil(tok::annot_pragma_openmp_end); + break; + } case OMPD_declare_reduction: ConsumeToken(); if (DeclGroupPtrTy Res = @@ -1602,6 +1657,7 @@ 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) diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index bd7f6dbee01..5d8cffae393 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -913,7 +913,8 @@ bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) { /// declaration: [C99 6.7] /// declaration-specifiers init-declarator-list[opt] ';' /// [!C99] init-declarator-list ';' [TODO: warn in c99 mode] -/// [OMP] threadprivate-directive [TODO] +/// [OMP] threadprivate-directive +/// [OMP] allocate-directive [TODO] /// Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs, diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7fed3725edd..6c4c4a845ce 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1908,7 +1908,8 @@ public: explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} bool ValidateCandidate(const TypoCorrection &Candidate) override { NamedDecl *ND = Candidate.getCorrectionDecl(); - if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) { + if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || + isa<FunctionDecl>(ND))) { return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), SemaRef.getCurScope()); } @@ -1920,7 +1921,8 @@ public: ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, - const DeclarationNameInfo &Id) { + const DeclarationNameInfo &Id, + OpenMPDirectiveKind Kind) { LookupResult Lookup(*this, Id, LookupOrdinaryName); LookupParsedName(Lookup, CurScope, &ScopeSpec, true); @@ -1953,9 +1955,9 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, // OpenMP [2.9.2, Syntax, C/C++] // Variables must be file-scope, namespace-scope, or static block-scope. - if (!VD->hasGlobalStorage()) { + if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { Diag(Id.getLoc(), diag::err_omp_global_var_arg) - << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); + << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -1972,7 +1974,7 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, if (CanonicalVD->getDeclContext()->isTranslationUnit() && !getCurLexicalContext()->isTranslationUnit()) { Diag(Id.getLoc(), diag::err_omp_var_scope) - << getOpenMPDirectiveName(OMPD_threadprivate) << VD; + << getOpenMPDirectiveName(Kind) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -1987,7 +1989,7 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, if (CanonicalVD->isStaticDataMember() && !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { Diag(Id.getLoc(), diag::err_omp_var_scope) - << getOpenMPDirectiveName(OMPD_threadprivate) << VD; + << getOpenMPDirectiveName(Kind) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -2003,7 +2005,7 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, (!getCurLexicalContext()->isFileContext() || !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { Diag(Id.getLoc(), diag::err_omp_var_scope) - << getOpenMPDirectiveName(OMPD_threadprivate) << VD; + << getOpenMPDirectiveName(Kind) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -2014,10 +2016,10 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, // OpenMP [2.9.2, Restrictions, C/C++, p.6] // A threadprivate directive for static block-scope variables must appear // in the scope of the variable and not in a nested scope. - if (CanonicalVD->isStaticLocal() && CurScope && + if (CanonicalVD->isLocalVarDecl() && CurScope && !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { Diag(Id.getLoc(), diag::err_omp_var_scope) - << getOpenMPDirectiveName(OMPD_threadprivate) << VD; + << getOpenMPDirectiveName(Kind) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -2029,9 +2031,10 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] // A threadprivate directive must lexically precede all references to any // of the variables in its list. - if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { + if (Kind == OMPD_threadprivate && VD->isUsed() && + !DSAStack->isThreadPrivate(VD)) { Diag(Id.getLoc(), diag::err_omp_var_used) - << getOpenMPDirectiveName(OMPD_threadprivate) << VD; + << getOpenMPDirectiveName(Kind) << VD; return ExprError(); } @@ -2164,6 +2167,41 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { } Sema::DeclGroupPtrTy +Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList, + DeclContext *Owner) { + SmallVector<Expr *, 8> Vars; + for (Expr *RefExpr : VarList) { + auto *DE = cast<DeclRefExpr>(RefExpr); + auto *VD = cast<VarDecl>(DE->getDecl()); + + // Check if this is a TLS variable or global register. + if (VD->getTLSKind() != VarDecl::TLS_None || + VD->hasAttr<OMPThreadPrivateDeclAttr>() || + (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && + !VD->isLocalVarDecl())) + continue; + // Do not apply for parameters. + if (isa<ParmVarDecl>(VD)) + continue; + + Vars.push_back(RefExpr); + VD->addAttr( + OMPAllocateDeclAttr::CreateImplicit(Context, DE->getSourceRange())); + if (ASTMutationListener *ML = Context.getASTMutationListener()) + ML->DeclarationMarkedOpenMPAllocate(VD, + VD->getAttr<OMPAllocateDeclAttr>()); + } + if (Vars.empty()) + return nullptr; + if (!Owner) + Owner = getCurLexicalContext(); + OMPAllocateDecl *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars); + D->setAccess(AS_public); + Owner->addDecl(D); + return DeclGroupPtrTy::make(DeclGroupRef(D)); +} + +Sema::DeclGroupPtrTy Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef<OMPClause *> ClauseList) { OMPRequiresDecl *D = nullptr; @@ -2863,6 +2901,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { break; } case OMPD_threadprivate: + case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: @@ -3719,6 +3758,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPD_declare_target: case OMPD_end_declare_target: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_declare_reduction: case OMPD_declare_mapper: case OMPD_declare_simd: @@ -8398,6 +8438,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_untied: case OMPC_mergeable: case OMPC_threadprivate: + case OMPC_allocate: case OMPC_flush: case OMPC_read: case OMPC_write: @@ -8482,6 +8523,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( // Do not capture if-clause expressions. break; case OMPD_threadprivate: + case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: @@ -8549,6 +8591,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_taskloop: case OMPD_taskloop_simd: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: @@ -8617,6 +8660,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_target_parallel_for: case OMPD_target_parallel_for_simd: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: @@ -8682,6 +8726,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_target_parallel_for: case OMPD_target_parallel_for_simd: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: @@ -8748,6 +8793,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_parallel: case OMPD_parallel_sections: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: @@ -8813,6 +8859,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_parallel: case OMPD_parallel_sections: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: @@ -8877,6 +8924,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_parallel_for: case OMPD_parallel_for_simd: case OMPD_threadprivate: + case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: @@ -8928,6 +8976,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPC_untied: case OMPC_mergeable: case OMPC_threadprivate: + case OMPC_allocate: case OMPC_flush: case OMPC_read: case OMPC_write: @@ -9251,6 +9300,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_untied: case OMPC_mergeable: case OMPC_threadprivate: + case OMPC_allocate: case OMPC_flush: case OMPC_read: case OMPC_write: @@ -9428,6 +9478,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_untied: case OMPC_mergeable: case OMPC_threadprivate: + case OMPC_allocate: case OMPC_flush: case OMPC_read: case OMPC_write: @@ -9645,6 +9696,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_default: case OMPC_proc_bind: case OMPC_threadprivate: + case OMPC_allocate: case OMPC_flush: case OMPC_depend: case OMPC_device: @@ -9841,6 +9893,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_untied: case OMPC_mergeable: case OMPC_threadprivate: + case OMPC_allocate: case OMPC_read: case OMPC_write: case OMPC_update: diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index db63529044b..73909fe6b59 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2876,6 +2876,21 @@ Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl( return TD; } +Decl *TemplateDeclInstantiator::VisitOMPAllocateDecl(OMPAllocateDecl *D) { + SmallVector<Expr *, 5> Vars; + for (auto *I : D->varlists()) { + Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get(); + assert(isa<DeclRefExpr>(Var) && "allocate arg is not a DeclRefExpr"); + Vars.push_back(Var); + } + + Sema::DeclGroupPtrTy Res = + SemaRef.ActOnOpenMPAllocateDirective(D->getLocation(), Vars, Owner); + if (Res.get().isNull()) + return nullptr; + return Res.get().getSingleDecl(); +} + Decl *TemplateDeclInstantiator::VisitOMPRequiresDecl(OMPRequiresDecl *D) { llvm_unreachable( "Requires directive cannot be instantiated within a dependent context"); diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 1e15cb4afdd..de95825f3cb 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -387,6 +387,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::ClassScopeFunctionSpecialization: case Decl::Import: case Decl::OMPThreadPrivate: + case Decl::OMPAllocate: case Decl::OMPRequires: case Decl::OMPCapturedExpr: case Decl::OMPDeclareReduction: diff --git a/clang/lib/Serialization/ASTCommon.h b/clang/lib/Serialization/ASTCommon.h index 2678103ac9a..296642e3674 100644 --- a/clang/lib/Serialization/ASTCommon.h +++ b/clang/lib/Serialization/ASTCommon.h @@ -38,6 +38,7 @@ enum DeclUpdateKind { UPD_MANGLING_NUMBER, UPD_STATIC_LOCAL_NUMBER, UPD_DECL_MARKED_OPENMP_THREADPRIVATE, + UPD_DECL_MARKED_OPENMP_ALLOCATE, UPD_DECL_MARKED_OPENMP_DECLARETARGET, UPD_DECL_EXPORTED, UPD_ADDED_ATTR_TO_RECORD diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index fb56170d8ab..760489d172d 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -444,6 +444,7 @@ namespace clang { void VisitObjCPropertyDecl(ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + void VisitOMPAllocateDecl(OMPAllocateDecl *D); void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D); void VisitOMPRequiresDecl(OMPRequiresDecl *D); @@ -2633,6 +2634,17 @@ void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { D->setVars(Vars); } +void ASTDeclReader::VisitOMPAllocateDecl(OMPAllocateDecl *D) { + VisitDecl(D); + unsigned NumVars = D->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) { + Vars.push_back(Record.readExpr()); + } + D->setVars(Vars); +} + void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) { VisitDecl(D); unsigned NumClauses = D->clauselist_size(); @@ -2795,7 +2807,7 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) { isa<PragmaDetectMismatchDecl>(D)) return true; if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D) || - isa<OMPDeclareMapperDecl>(D)) + isa<OMPDeclareMapperDecl>(D) || isa<OMPAllocateDecl>(D)) return !D->getDeclContext()->isFunctionOrMethod(); if (const auto *Var = dyn_cast<VarDecl>(D)) return Var->isFileVarDecl() && @@ -3866,6 +3878,9 @@ 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()); + break; case DECL_OMP_REQUIRES: D = OMPRequiresDecl::CreateDeserialized(Context, ID, Record.readInt()); break; @@ -4465,6 +4480,11 @@ void ASTDeclReader::UpdateDecl(Decl *D, ReadSourceRange())); break; + case UPD_DECL_MARKED_OPENMP_ALLOCATE: + D->addAttr(OMPAllocateDeclAttr::CreateImplicit(Reader.getContext(), + ReadSourceRange())); + break; + case UPD_DECL_EXPORTED: { unsigned SubmoduleID = readSubmoduleID(); auto *Exported = cast<NamedDecl>(D); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 3d19c9d8231..06c477e9487 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1298,6 +1298,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_PRAGMA_COMMENT); RECORD(DECL_PRAGMA_DETECT_MISMATCH); RECORD(DECL_OMP_DECLARE_REDUCTION); + RECORD(DECL_OMP_ALLOCATE); // Statements and Exprs can occur in the Decls and Types block. AddStmtsExprs(Stream, Record); @@ -5287,6 +5288,10 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { D->getAttr<OMPThreadPrivateDeclAttr>()->getRange()); break; + case UPD_DECL_MARKED_OPENMP_ALLOCATE: + Record.AddSourceRange(D->getAttr<OMPAllocateDeclAttr>()->getRange()); + break; + case UPD_DECL_MARKED_OPENMP_DECLARETARGET: Record.push_back(D->getAttr<OMPDeclareTargetDeclAttr>()->getMapType()); Record.AddSourceRange( @@ -6404,6 +6409,15 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) { DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE)); } +void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) { + if (Chain && Chain->isProcessingUpdateRecords()) return; + assert(!WritingAST && "Already writing the AST!"); + if (!D->isFromASTFile()) + return; + + DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_ALLOCATE, A)); +} + void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D, const Attr *Attr) { if (Chain && Chain->isProcessingUpdateRecords()) return; diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 6de1320be42..cfcd81b3e1e 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -144,6 +144,7 @@ namespace clang { void VisitObjCPropertyDecl(ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + void VisitOMPAllocateDecl(OMPAllocateDecl *D); void VisitOMPRequiresDecl(OMPRequiresDecl *D); void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D); @@ -1744,10 +1745,18 @@ void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { Code = serialization::DECL_OMP_THREADPRIVATE; } +void ASTDeclWriter::VisitOMPAllocateDecl(OMPAllocateDecl *D) { + Record.push_back(D->varlist_size()); + VisitDecl(D); + for (auto *I : D->varlists()) + Record.AddStmt(I); + Code = serialization::DECL_OMP_ALLOCATE; +} + void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) { Record.push_back(D->clauselist_size()); VisitDecl(D); - OMPClauseWriter ClauseWriter(Record); + OMPClauseWriter ClauseWriter(Record); for (OMPClause *C : D->clauselists()) ClauseWriter.writeClause(C); Code = serialization::DECL_OMP_REQUIRES; |