summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp4
-rw-r--r--clang/lib/AST/DeclBase.cpp1
-rw-r--r--clang/lib/AST/DeclOpenMP.cpp30
-rw-r--r--clang/lib/AST/DeclPrinter.cpp18
-rw-r--r--clang/lib/AST/OpenMPClause.cpp2
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp6
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp1
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp3
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp6
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp1
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp3
-rw-r--r--clang/lib/Frontend/MultiplexConsumer.cpp6
-rw-r--r--clang/lib/Parse/ParseDecl.cpp3
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp76
-rw-r--r--clang/lib/Parse/Parser.cpp3
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp75
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp15
-rw-r--r--clang/lib/Serialization/ASTCommon.cpp1
-rw-r--r--clang/lib/Serialization/ASTCommon.h1
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp22
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp14
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp11
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;
OpenPOWER on IntegriCloud