summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTDumper.cpp5
-rw-r--r--lib/AST/CXXInheritance.cpp15
-rw-r--r--lib/AST/DeclBase.cpp4
-rw-r--r--lib/AST/DeclOpenMP.cpp50
-rw-r--r--lib/AST/DeclPrinter.cpp22
-rw-r--r--lib/AST/ItaniumMangle.cpp3
-rw-r--r--lib/AST/MicrosoftMangle.cpp3
-rw-r--r--lib/Basic/OpenMPKinds.cpp11
-rw-r--r--lib/CodeGen/CGDecl.cpp10
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp3
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp4
-rw-r--r--lib/CodeGen/CodeGenModule.cpp8
-rw-r--r--lib/CodeGen/CodeGenModule.h4
-rw-r--r--lib/Parse/ParseOpenMP.cpp171
-rw-r--r--lib/Sema/SemaDecl.cpp5
-rw-r--r--lib/Sema/SemaExpr.cpp14
-rw-r--r--lib/Sema/SemaLookup.cpp8
-rw-r--r--lib/Sema/SemaOpenMP.cpp146
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp84
-rw-r--r--lib/Serialization/ASTCommon.cpp1
-rw-r--r--lib/Serialization/ASTReader.cpp4
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp23
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp14
23 files changed, 602 insertions, 10 deletions
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 7cb61c8aff..e539290fcc 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -381,6 +381,11 @@ namespace {
Visit(Initializer);
}
+ void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {
+ for (const auto *C : D->clauselists())
+ Visit(C);
+ }
+
void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
Visit(D->getInit());
}
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 1c0649a769..150b598215 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -486,6 +486,21 @@ bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
return false;
}
+bool CXXRecordDecl::FindOMPMapperMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path,
+ DeclarationName Name) {
+ RecordDecl *BaseRecord =
+ Specifier->getType()->castAs<RecordType>()->getDecl();
+
+ for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty();
+ Path.Decls = Path.Decls.slice(1)) {
+ if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPMapper))
+ return true;
+ }
+
+ return false;
+}
+
bool CXXRecordDecl::
FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 2d6fbddd0d..a44c839815 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -780,6 +780,9 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case OMPDeclareReduction:
return IDNS_OMPReduction;
+ case OMPDeclareMapper:
+ return IDNS_OMPMapper;
+
// Never have names.
case Friend:
case FriendTemplate:
@@ -1163,6 +1166,7 @@ DeclContext *DeclContext::getPrimaryContext() {
case Decl::Block:
case Decl::Captured:
case Decl::OMPDeclareReduction:
+ case Decl::OMPDeclareMapper:
// There is only one DeclContext for these entities.
return this;
diff --git a/lib/AST/DeclOpenMP.cpp b/lib/AST/DeclOpenMP.cpp
index f709013ba9..5a1b036313 100644
--- a/lib/AST/DeclOpenMP.cpp
+++ b/lib/AST/DeclOpenMP.cpp
@@ -123,6 +123,56 @@ OMPDeclareReductionDecl::getPrevDeclInScope() const {
}
//===----------------------------------------------------------------------===//
+// OMPDeclareMapperDecl Implementation.
+//===----------------------------------------------------------------------===//
+
+void OMPDeclareMapperDecl::anchor() {}
+
+OMPDeclareMapperDecl *
+OMPDeclareMapperDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, QualType T,
+ DeclarationName VarName,
+ OMPDeclareMapperDecl *PrevDeclInScope) {
+ return new (C, DC) OMPDeclareMapperDecl(OMPDeclareMapper, DC, L, Name, T,
+ VarName, PrevDeclInScope);
+}
+
+OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID,
+ unsigned N) {
+ auto *D = new (C, ID)
+ OMPDeclareMapperDecl(OMPDeclareMapper, /*DC=*/nullptr, SourceLocation(),
+ DeclarationName(), QualType(), DeclarationName(),
+ /*PrevDeclInScope=*/nullptr);
+ if (N) {
+ auto **ClauseStorage = C.Allocate<OMPClause *>(N);
+ D->Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, N);
+ }
+ return D;
+}
+
+/// Creates an array of clauses to this mapper declaration and intializes
+/// them. The space used to store clause pointers is dynamically allocated,
+/// because we do not know the number of clauses when creating
+/// OMPDeclareMapperDecl
+void OMPDeclareMapperDecl::CreateClauses(ASTContext &C,
+ ArrayRef<OMPClause *> CL) {
+ assert(Clauses.empty() && "Number of clauses should be 0 on initialization");
+ size_t NumClauses = CL.size();
+ if (NumClauses) {
+ auto **ClauseStorage = C.Allocate<OMPClause *>(NumClauses);
+ Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
+ setClauses(CL);
+ }
+}
+
+void OMPDeclareMapperDecl::setClauses(ArrayRef<OMPClause *> CL) {
+ assert(CL.size() == Clauses.size() &&
+ "Number of clauses is not the same as the preallocated buffer");
+ std::uninitialized_copy(CL.begin(), CL.end(), Clauses.data());
+}
+
+//===----------------------------------------------------------------------===//
// OMPCapturedExprDecl Implementation.
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index a3e8475a1e..46069898cc 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -101,6 +101,7 @@ namespace {
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
+ void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
void printTemplateParameters(const TemplateParameterList *Params);
@@ -423,7 +424,7 @@ 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<OMPRequiresDecl>(*D))
+ isa<OMPDeclareMapperDecl>(*D) || isa<OMPRequiresDecl>(*D))
Terminator = nullptr;
else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody())
Terminator = nullptr;
@@ -1597,6 +1598,25 @@ void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
}
}
+void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
+ if (!D->isInvalidDecl()) {
+ Out << "#pragma omp declare mapper (";
+ D->printName(Out);
+ Out << " : ";
+ D->getType().print(Out, Policy);
+ Out << " ";
+ Out << D->getVarName();
+ Out << ")";
+ if (!D->clauselist_empty()) {
+ OMPClausePrinter Printer(Out, Policy);
+ for (auto *C : D->clauselists()) {
+ Out << " ";
+ Printer.Visit(C);
+ }
+ }
+ }
+}
+
void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
D->getInit()->printPretty(Out, nullptr, Policy, Indentation);
}
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 34a6181bd4..5d5d857c44 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -60,7 +60,8 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) {
}
const DeclContext *DC = D->getDeclContext();
- if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) {
+ if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
+ isa<OMPDeclareMapperDecl>(DC)) {
return getEffectiveDeclContext(cast<Decl>(DC));
}
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 471e738bbb..b2d961a439 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -96,7 +96,8 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) {
}
const DeclContext *DC = D->getDeclContext();
- if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) {
+ if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
+ isa<OMPDeclareMapperDecl>(DC)) {
return getEffectiveDeclContext(cast<Decl>(DC));
}
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index c421517006..ea8a46b495 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -766,6 +766,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
+ case OMPD_declare_mapper:
+ switch (CKind) {
+#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_unknown:
@@ -1000,6 +1010,7 @@ void clang::getOpenMPCaptureRegions(
case OMPD_cancel:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 6e8f85430a..72fd902ece 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -141,6 +141,9 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::OMPDeclareReduction:
return CGM.EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(&D), this);
+ case Decl::OMPDeclareMapper:
+ return CGM.EmitOMPDeclareMapper(cast<OMPDeclareMapperDecl>(&D), this);
+
case Decl::Typedef: // typedef int X;
case Decl::TypeAlias: { // using X = int; [C++0x]
const TypedefNameDecl &TD = cast<TypedefNameDecl>(D);
@@ -2416,6 +2419,13 @@ void CodeGenModule::EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
getOpenMPRuntime().emitUserDefinedReduction(CGF, D);
}
+void CodeGenModule::EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D,
+ CodeGenFunction *CGF) {
+ if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && !D->isUsed()))
+ return;
+ // FIXME: need to implement mapper code generation
+}
+
void CodeGenModule::EmitOMPRequiresDecl(const OMPRequiresDecl *D) {
getOpenMPRuntime().checkArchForUnifiedAddressing(*this, D);
}
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index ad02ee6e21..f650bd98e6 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -8230,6 +8230,7 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -8652,6 +8653,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -9132,6 +9134,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall(
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_target:
diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 788fa83ea0..ca9673096e 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -858,6 +858,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -926,6 +927,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -1076,6 +1078,7 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -1149,6 +1152,7 @@ static bool supportsLightweightRuntime(ASTContext &Ctx,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index b8004452f8..199ec59835 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -2191,6 +2191,10 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
if (MustBeEmitted(Global))
EmitOMPDeclareReduction(DRD);
return;
+ } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Global)) {
+ if (MustBeEmitted(Global))
+ EmitOMPDeclareMapper(DMD);
+ return;
}
}
@@ -5053,6 +5057,10 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(D));
break;
+ case Decl::OMPDeclareMapper:
+ EmitOMPDeclareMapper(cast<OMPDeclareMapperDecl>(D));
+ break;
+
case Decl::OMPRequires:
EmitOMPRequiresDecl(cast<OMPRequiresDecl>(D));
break;
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 35e94d7bb0..5d146daee8 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -1243,6 +1243,10 @@ public:
void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
CodeGenFunction *CGF = nullptr);
+ /// Emit a code for declare mapper construct.
+ void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D,
+ CodeGenFunction *CGF = nullptr);
+
/// Emit a code for requires directive.
/// \param D Requires declaration
void EmitOMPRequiresDecl(const OMPRequiresDecl *D);
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index 2308e6e3da..5b8670e928 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -40,7 +40,8 @@ enum OpenMPDirectiveKindEx {
OMPD_update,
OMPD_distribute_parallel,
OMPD_teams_distribute_parallel,
- OMPD_target_teams_distribute_parallel
+ OMPD_target_teams_distribute_parallel,
+ OMPD_mapper,
};
class ThreadprivateListParserHelper final {
@@ -76,6 +77,7 @@ static unsigned getOpenMPDirectiveKindEx(StringRef S) {
.Case("point", OMPD_point)
.Case("reduction", OMPD_reduction)
.Case("update", OMPD_update)
+ .Case("mapper", OMPD_mapper)
.Default(OMPD_unknown);
}
@@ -86,6 +88,7 @@ static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
static const unsigned F[][3] = {
{OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
{OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
+ {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
{OMPD_declare, OMPD_simd, OMPD_declare_simd},
{OMPD_declare, OMPD_target, OMPD_declare_target},
{OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
@@ -469,6 +472,141 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
}
}
+/// Parses 'omp declare mapper' directive.
+///
+/// declare-mapper-directive:
+/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
+/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
+/// annot_pragma_openmp_end
+/// <mapper-identifier> and <var> are base language identifiers.
+///
+Parser::DeclGroupPtrTy
+Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
+ bool IsCorrect = true;
+ // Parse '('
+ BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
+ if (T.expectAndConsume(diag::err_expected_lparen_after,
+ getOpenMPDirectiveName(OMPD_declare_mapper))) {
+ SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+ return DeclGroupPtrTy();
+ }
+
+ // Parse <mapper-identifier>
+ auto &DeclNames = Actions.getASTContext().DeclarationNames;
+ DeclarationName MapperId;
+ if (PP.LookAhead(0).is(tok::colon)) {
+ if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
+ Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
+ IsCorrect = false;
+ } else {
+ MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
+ }
+ ConsumeToken();
+ // Consume ':'.
+ ExpectAndConsume(tok::colon);
+ } else {
+ // If no mapper identifier is provided, its name is "default" by default
+ MapperId =
+ DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
+ }
+
+ if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
+ return DeclGroupPtrTy();
+
+ // Parse <type> <var>
+ DeclarationName VName;
+ QualType MapperType;
+ SourceRange Range;
+ TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
+ if (ParsedType.isUsable())
+ MapperType =
+ Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
+ if (MapperType.isNull())
+ IsCorrect = false;
+ if (!IsCorrect) {
+ SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
+ return DeclGroupPtrTy();
+ }
+
+ // Consume ')'.
+ IsCorrect &= !T.consumeClose();
+ if (!IsCorrect) {
+ SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
+ return DeclGroupPtrTy();
+ }
+
+ // Enter scope.
+ OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
+ getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
+ Range.getBegin(), VName, AS);
+ DeclarationNameInfo DirName;
+ SourceLocation Loc = Tok.getLocation();
+ unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
+ Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
+ ParseScope OMPDirectiveScope(this, ScopeFlags);
+ Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
+
+ // Add the mapper variable declaration.
+ Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
+ DMD, getCurScope(), MapperType, Range.getBegin(), VName);
+
+ // Parse map clauses.
+ SmallVector<OMPClause *, 6> Clauses;
+ 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_declare_mapper, CKind, Clauses.size() == 0);
+ if (Clause)
+ Clauses.push_back(Clause);
+ else
+ IsCorrect = false;
+ // Skip ',' if any.
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ Actions.EndOpenMPClause();
+ }
+ if (Clauses.empty()) {
+ Diag(Tok, diag::err_omp_expected_clause)
+ << getOpenMPDirectiveName(OMPD_declare_mapper);
+ IsCorrect = false;
+ }
+
+ // Exit scope.
+ Actions.EndOpenMPDSABlock(nullptr);
+ OMPDirectiveScope.Exit();
+
+ DeclGroupPtrTy DGP =
+ Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
+ if (!IsCorrect)
+ return DeclGroupPtrTy();
+ return DGP;
+}
+
+TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
+ DeclarationName &Name,
+ AccessSpecifier AS) {
+ // Parse the common declaration-specifiers piece.
+ Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
+ DeclSpec DS(AttrFactory);
+ ParseSpecifierQualifierList(DS, AS, DSC);
+
+ // Parse the declarator.
+ DeclaratorContext Context = DeclaratorContext::PrototypeContext;
+ Declarator DeclaratorInfo(DS, Context);
+ ParseDeclarator(DeclaratorInfo);
+ Range = DeclaratorInfo.getSourceRange();
+ if (DeclaratorInfo.getIdentifier() == nullptr) {
+ Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
+ return true;
+ }
+ Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
+
+ return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
+}
+
namespace {
/// RAII that recreates function context for correct parsing of clauses of
/// 'declare simd' construct.
@@ -707,6 +845,11 @@ void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
/// annot_pragma_openmp 'declare' 'reduction' [...]
/// annot_pragma_openmp_end
///
+/// declare-mapper-directive:
+/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
+/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
+/// annot_pragma_openmp_end
+///
/// declare-simd-directive:
/// annot_pragma_openmp 'declare simd' {<clause> [,]}
/// annot_pragma_openmp_end
@@ -800,6 +943,15 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
return Res;
}
break;
+ case OMPD_declare_mapper: {
+ ConsumeToken();
+ if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
+ // Skip the last annot_pragma_openmp_end.
+ ConsumeAnnotationToken();
+ return Res;
+ }
+ break;
+ }
case OMPD_declare_simd: {
// The syntax is:
// { #pragma omp declare simd }
@@ -954,6 +1106,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
/// ('omp_priv' '=' <expression>|<function_call>) ')']
/// annot_pragma_openmp_end
///
+/// declare-mapper-directive:
+/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
+/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
+/// annot_pragma_openmp_end
+///
/// executable-directive:
/// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
@@ -1034,6 +1191,18 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
SkipUntil(tok::annot_pragma_openmp_end);
}
break;
+ case OMPD_declare_mapper: {
+ ConsumeToken();
+ if (DeclGroupPtrTy Res =
+ ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
+ // Skip the last annot_pragma_openmp_end.
+ ConsumeAnnotationToken();
+ Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
+ } else {
+ SkipUntil(tok::annot_pragma_openmp_end);
+ }
+ break;
+ }
case OMPD_flush:
if (PP.LookAhead(0).is(tok::l_paren)) {
FlushHasClause = true;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 136162ad0f..5b6fd880ca 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -6192,7 +6192,8 @@ static bool isIncompleteDeclExternC(Sema &S, const T *D) {
static bool shouldConsiderLinkage(const VarDecl *VD) {
const DeclContext *DC = VD->getDeclContext()->getRedeclContext();
- if (DC->isFunctionOrMethod() || isa<OMPDeclareReductionDecl>(DC))
+ if (DC->isFunctionOrMethod() || isa<OMPDeclareReductionDecl>(DC) ||
+ isa<OMPDeclareMapperDecl>(DC))
return VD->hasExternalStorage();
if (DC->isFileContext())
return true;
@@ -6204,7 +6205,7 @@ static bool shouldConsiderLinkage(const VarDecl *VD) {
static bool shouldConsiderLinkage(const FunctionDecl *FD) {
const DeclContext *DC = FD->getDeclContext()->getRedeclContext();
if (DC->isFileContext() || DC->isFunctionOrMethod() ||
- isa<OMPDeclareReductionDecl>(DC))
+ isa<OMPDeclareReductionDecl>(DC) || isa<OMPDeclareMapperDecl>(DC))
return true;
if (DC->isRecord())
return false;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 15957ae49d..b675986f56 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -310,6 +310,19 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
return true;
}
+ // [OpenMP 5.0], 2.19.7.3. declare mapper Directive, Restrictions
+ // List-items in map clauses on this construct may only refer to the declared
+ // variable var and entities that could be referenced by a procedure defined
+ // at the same location
+ auto *DMD = dyn_cast<OMPDeclareMapperDecl>(CurContext);
+ if (LangOpts.OpenMP && DMD && !CurContext->containsDecl(D) &&
+ isa<VarDecl>(D)) {
+ Diag(Loc, diag::err_omp_declare_mapper_wrong_var)
+ << DMD->getVarName().getAsString();
+ Diag(D->getLocation(), diag::note_entity_declared_at) << D;
+ return true;
+ }
+
DiagnoseAvailabilityOfDecl(D, Locs, UnknownObjCClass, ObjCPropertyAccess,
AvoidPartialAvailabilityChecks, ClassReceiver);
@@ -2988,6 +3001,7 @@ ExprResult Sema::BuildDeclarationNameExpr(
case Decl::EnumConstant:
case Decl::UnresolvedUsingValue:
case Decl::OMPDeclareReduction:
+ case Decl::OMPDeclareMapper:
valueKind = VK_RValue;
break;
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 653fc133b2..249be78098 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -278,6 +278,10 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
IDNS = Decl::IDNS_OMPReduction;
break;
+ case Sema::LookupOMPMapperName:
+ IDNS = Decl::IDNS_OMPMapper;
+ break;
+
case Sema::LookupAnyName:
IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member
| Decl::IDNS_Using | Decl::IDNS_Namespace | Decl::IDNS_ObjCProtocol
@@ -2103,6 +2107,10 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
BaseCallback = &CXXRecordDecl::FindOMPReductionMember;
break;
+ case LookupOMPMapperName:
+ BaseCallback = &CXXRecordDecl::FindOMPMapperMember;
+ break;
+
case LookupUsingDeclName:
// This lookup is for redeclarations only.
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 59a40ec41c..6b345bfd23 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -2808,6 +2808,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
case OMPD_cancel:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -3656,6 +3657,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPD_end_declare_target:
case OMPD_threadprivate:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_requires:
llvm_unreachable("OpenMP Directive is not allowed");
@@ -8435,6 +8437,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8501,6 +8504,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8568,6 +8572,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8632,6 +8637,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8697,6 +8703,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8761,6 +8768,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8824,6 +8832,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -13464,6 +13473,143 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
return DeclReductions;
}
+TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
+ TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
+ QualType T = TInfo->getType();
+ if (D.isInvalidType())
+ return true;
+
+ if (getLangOpts().CPlusPlus) {
+ // Check that there are no default arguments (C++ only).
+ CheckExtraCXXDefaultArguments(D);
+ }
+
+ return CreateParsedType(T, TInfo);
+}
+
+QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
+ TypeResult ParsedType) {
+ assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
+
+ QualType MapperType = GetTypeFromParser(ParsedType.get());
+ assert(!MapperType.isNull() && "Expect valid mapper type");
+
+ // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
+ // The type must be of struct, union or class type in C and C++
+ if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
+ Diag(TyLoc, diag::err_omp_mapper_wrong_type);
+ return QualType();
+ }
+ return MapperType;
+}
+
+OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
+ Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
+ SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
+ Decl *PrevDeclInScope) {
+ LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
+ forRedeclarationInCurContext());
+ // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
+ // A mapper-identifier may not be redeclared in the current scope for the
+ // same type or for a type that is compatible according to the base language
+ // rules.
+ llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
+ OMPDeclareMapperDecl *PrevDMD = nullptr;
+ bool InCompoundScope = true;
+ if (S != nullptr) {
+ // Find previous declaration with the same name not referenced in other
+ // declarations.
+ FunctionScopeInfo *ParentFn = getEnclosingFunction();
+ InCompoundScope =
+ (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
+ LookupName(Lookup, S);
+ FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
+ /*AllowInlineNamespace=*/false);
+ llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
+ LookupResult::Filter Filter = Lookup.makeFilter();
+ while (Filter.hasNext()) {
+ auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
+ if (InCompoundScope) {
+ auto I = UsedAsPrevious.find(PrevDecl);
+ if (I == UsedAsPrevious.end())
+ UsedAsPrevious[PrevDecl] = false;
+ if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
+ UsedAsPrevious[D] = true;
+ }
+ PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
+ PrevDecl->getLocation();
+ }
+ Filter.done();
+ if (InCompoundScope) {
+ for (const auto &PrevData : UsedAsPrevious) {
+ if (!PrevData.second) {
+ PrevDMD = PrevData.first;
+ break;
+ }
+ }
+ }
+ } else if (PrevDeclInScope) {
+ auto *PrevDMDInScope = PrevDMD =
+ cast<OMPDeclareMapperDecl>(PrevDeclInScope);
+ do {
+ PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
+ PrevDMDInScope->getLocation();
+ PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
+ } while (PrevDMDInScope != nullptr);
+ }
+ const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
+ bool Invalid = false;
+ if (I != PreviousRedeclTypes.end()) {
+ Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
+ << MapperType << Name;
+ Diag(I->second, diag::note_previous_definition);
+ Invalid = true;
+ }
+ auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
+ MapperType, VN, PrevDMD);
+ DC->addDecl(DMD);
+ DMD->setAccess(AS);
+ if (Invalid)
+ DMD->setInvalidDecl();
+
+ // Enter new function scope.
+ PushFunctionScope();
+ setFunctionHasBranchProtectedScope();
+
+ CurContext = DMD;
+
+ return DMD;
+}
+
+void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
+ Scope *S,
+ QualType MapperType,
+ SourceLocation StartLoc,
+ DeclarationName VN) {
+ VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
+ if (S)
+ PushOnScopeChains(VD, S);
+ else
+ DMD->addDecl(VD);
+ Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
+ DMD->setMapperVarRef(MapperVarRefExpr);
+}
+
+Sema::DeclGroupPtrTy
+Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
+ ArrayRef<OMPClause *> ClauseList) {
+ PopDeclContext();
+ PopFunctionScopeInfo();
+
+ if (D) {
+ if (S)
+ PushOnScopeChains(D, S, /*AddToContext=*/false);
+ D->CreateClauses(Context, ClauseList);
+ }
+
+ return DeclGroupPtrTy::make(DeclGroupRef(D));
+}
+
OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
SourceLocation StartLoc,
SourceLocation LParenLoc,
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 883a73f226..e3f57e0038 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2924,6 +2924,87 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
return NewDRD;
}
+Decl *
+TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
+ // Instantiate type and check if it is allowed.
+ const bool RequiresInstantiation =
+ D->getType()->isDependentType() ||
+ D->getType()->isInstantiationDependentType() ||
+ D->getType()->containsUnexpandedParameterPack();
+ QualType SubstMapperTy;
+ DeclarationName VN = D->getVarName();
+ if (RequiresInstantiation) {
+ SubstMapperTy = SemaRef.ActOnOpenMPDeclareMapperType(
+ D->getLocation(),
+ ParsedType::make(SemaRef.SubstType(D->getType(), TemplateArgs,
+ D->getLocation(), VN)));
+ } else {
+ SubstMapperTy = D->getType();
+ }
+ if (SubstMapperTy.isNull())
+ return nullptr;
+ // Create an instantiated copy of mapper.
+ auto *PrevDeclInScope = D->getPrevDeclInScope();
+ if (PrevDeclInScope && !PrevDeclInScope->isInvalidDecl()) {
+ PrevDeclInScope = cast<OMPDeclareMapperDecl>(
+ SemaRef.CurrentInstantiationScope->findInstantiationOf(PrevDeclInScope)
+ ->get<Decl *>());
+ }
+ OMPDeclareMapperDecl *NewDMD = SemaRef.ActOnOpenMPDeclareMapperDirectiveStart(
+ /*S=*/nullptr, Owner, D->getDeclName(), SubstMapperTy, D->getLocation(),
+ VN, D->getAccess(), PrevDeclInScope);
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDMD);
+ SmallVector<OMPClause *, 6> Clauses;
+ bool IsCorrect = true;
+ if (!RequiresInstantiation) {
+ // Copy the mapper variable.
+ NewDMD->setMapperVarRef(D->getMapperVarRef());
+ // Copy map clauses from the original mapper.
+ for (OMPClause *C : D->clauselists())
+ Clauses.push_back(C);
+ } else {
+ // Instantiate the mapper variable.
+ DeclarationNameInfo DirName;
+ SemaRef.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, /*S=*/nullptr,
+ (*D->clauselist_begin())->getBeginLoc());
+ SemaRef.ActOnOpenMPDeclareMapperDirectiveVarDecl(
+ NewDMD, /*S=*/nullptr, SubstMapperTy, D->getLocation(), VN);
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(
+ cast<DeclRefExpr>(D->getMapperVarRef())->getDecl(),
+ cast<DeclRefExpr>(NewDMD->getMapperVarRef())->getDecl());
+ auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
+ Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
+ ThisContext);
+ // Instantiate map clauses.
+ for (OMPClause *C : D->clauselists()) {
+ auto *OldC = cast<OMPMapClause>(C);
+ SmallVector<Expr *, 4> NewVars;
+ for (Expr *OE : OldC->varlists()) {
+ Expr *NE = SemaRef.SubstExpr(OE, TemplateArgs).get();
+ if (!NE) {
+ IsCorrect = false;
+ break;
+ }
+ NewVars.push_back(NE);
+ }
+ if (!IsCorrect)
+ break;
+ OMPClause *NewC = SemaRef.ActOnOpenMPMapClause(
+ OldC->getMapTypeModifiers(), OldC->getMapTypeModifiersLoc(),
+ OldC->getMapType(), OldC->isImplicitMapType(), OldC->getMapLoc(),
+ OldC->getColonLoc(), NewVars, OldC->getBeginLoc(),
+ OldC->getLParenLoc(), OldC->getEndLoc());
+ Clauses.push_back(NewC);
+ }
+ SemaRef.EndOpenMPDSABlock(nullptr);
+ }
+ (void)SemaRef.ActOnOpenMPDeclareMapperDirectiveEnd(NewDMD, /*S=*/nullptr,
+ Clauses);
+ if (!IsCorrect)
+ return nullptr;
+ return NewDMD;
+}
+
Decl *TemplateDeclInstantiator::VisitOMPCapturedExprDecl(
OMPCapturedExprDecl * /*D*/) {
llvm_unreachable("Should not be met in templates");
@@ -5005,7 +5086,8 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
((ParentDC->isFunctionOrMethod() ||
- isa<OMPDeclareReductionDecl>(ParentDC)) &&
+ isa<OMPDeclareReductionDecl>(ParentDC) ||
+ isa<OMPDeclareMapperDecl>(ParentDC)) &&
ParentDC->isDependentContext()) ||
(isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) {
// D is a local of some kind. Look into the map of local
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
index a54ba5fabf..1e15cb4afd 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/lib/Serialization/ASTCommon.cpp
@@ -390,6 +390,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {
case Decl::OMPRequires:
case Decl::OMPCapturedExpr:
case Decl::OMPDeclareReduction:
+ case Decl::OMPDeclareMapper:
case Decl::BuiltinTemplate:
case Decl::Decomposition:
case Decl::Binding:
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index def42ac720..aaf40b93f1 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -12300,7 +12300,7 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
SmallVector<Expr *, 16> Vars;
Vars.reserve(NumVars);
for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
+ Vars.push_back(Record.readExpr());
C->setVarRefs(Vars);
SmallVector<ValueDecl *, 16> Decls;
@@ -12324,7 +12324,7 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
Components.reserve(TotalComponents);
for (unsigned i = 0; i < TotalComponents; ++i) {
- Expr *AssociatedExpr = Record.readSubExpr();
+ Expr *AssociatedExpr = Record.readExpr();
auto *AssociatedDecl = Record.readDeclAs<ValueDecl>();
Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
AssociatedExpr, AssociatedDecl));
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 8b40dc853b..1c56cdbf94 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -445,6 +445,7 @@ namespace clang {
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
+ void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
};
@@ -2659,6 +2660,22 @@ void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
D->PrevDeclInScope = ReadDeclID();
}
+void ASTDeclReader::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
+ VisitValueDecl(D);
+ D->setLocation(ReadSourceLocation());
+ Expr *MapperVarRefE = Record.readExpr();
+ D->setMapperVarRef(MapperVarRefE);
+ D->VarName = Record.readDeclarationName();
+ D->PrevDeclInScope = ReadDeclID();
+ unsigned NumClauses = D->clauselist_size();
+ 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::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
VisitVarDecl(D);
}
@@ -2776,7 +2793,8 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
isa<PragmaCommentDecl>(D) ||
isa<PragmaDetectMismatchDecl>(D))
return true;
- if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D))
+ if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D) ||
+ isa<OMPDeclareMapperDecl>(D))
return !D->getDeclContext()->isFunctionOrMethod();
if (const auto *Var = dyn_cast<VarDecl>(D))
return Var->isFileVarDecl() &&
@@ -3853,6 +3871,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
case DECL_OMP_DECLARE_REDUCTION:
D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID);
break;
+ case DECL_OMP_DECLARE_MAPPER:
+ D = OMPDeclareMapperDecl::CreateDeserialized(Context, ID, Record.readInt());
+ break;
case DECL_OMP_CAPTUREDEXPR:
D = OMPCapturedExprDecl::CreateDeserialized(Context, ID);
break;
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 16fdb54ee9..bd5191dcb9 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -146,6 +146,7 @@ namespace clang {
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
+ void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
/// Add an Objective-C type parameter list to the given record.
@@ -1765,6 +1766,19 @@ void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
Code = serialization::DECL_OMP_DECLARE_REDUCTION;
}
+void ASTDeclWriter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
+ Record.push_back(D->clauselist_size());
+ VisitValueDecl(D);
+ Record.AddSourceLocation(D->getBeginLoc());
+ Record.AddStmt(D->getMapperVarRef());
+ Record.AddDeclarationName(D->getVarName());
+ Record.AddDeclRef(D->getPrevDeclInScope());
+ OMPClauseWriter ClauseWriter(Record);
+ for (OMPClause *C : D->clauselists())
+ ClauseWriter.writeClause(C);
+ Code = serialization::DECL_OMP_DECLARE_MAPPER;
+}
+
void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
VisitVarDecl(D);
Code = serialization::DECL_OMP_CAPTUREDEXPR;