summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp5
-rw-r--r--clang/lib/Sema/SemaExpr.cpp14
-rw-r--r--clang/lib/Sema/SemaLookup.cpp8
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp146
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp84
5 files changed, 254 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 136162ad0fa..5b6fd880ca8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 15957ae49d3..b675986f56b 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/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/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 653fc133b2a..249be780985 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/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/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 59a40ec41c7..6b345bfd239 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/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/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 883a73f2266..e3f57e00381 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/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
OpenPOWER on IntegriCloud