diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 146 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 84 |
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 |