aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp1065
1 files changed, 740 insertions, 325 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 920463da4027..78707484f588 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -35,6 +35,7 @@
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/PointerEmbeddedInt.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include <set>
@@ -48,7 +49,7 @@ using namespace llvm::omp;
static const Expr *checkMapClauseExpressionBase(
Sema &SemaRef, Expr *E,
OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
- OpenMPClauseKind CKind, bool NoDiagnose);
+ OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
namespace {
/// Default data sharing attributes, which can be applied to directive.
@@ -70,12 +71,15 @@ public:
const Expr *RefExpr = nullptr;
DeclRefExpr *PrivateCopy = nullptr;
SourceLocation ImplicitDSALoc;
+ bool AppliedToPointee = false;
DSAVarData() = default;
DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
const Expr *RefExpr, DeclRefExpr *PrivateCopy,
- SourceLocation ImplicitDSALoc, unsigned Modifier)
+ SourceLocation ImplicitDSALoc, unsigned Modifier,
+ bool AppliedToPointee)
: DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
- PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
+ PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
+ AppliedToPointee(AppliedToPointee) {}
};
using OperatorOffsetTy =
llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
@@ -99,6 +103,9 @@ private:
/// variable is marked as lastprivate(true) or not (false).
llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
DeclRefExpr *PrivateCopy = nullptr;
+ /// true if the attribute is applied to the pointee, not the variable
+ /// itself.
+ bool AppliedToPointee = false;
};
using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
@@ -153,6 +160,7 @@ private:
OpenMPDirectiveKind Directive = OMPD_unknown;
DeclarationNameInfo DirectiveName;
Scope *CurScope = nullptr;
+ DeclContext *Context = nullptr;
SourceLocation ConstructLoc;
/// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
/// get the data (loop counters etc.) about enclosing loop-based construct.
@@ -184,6 +192,7 @@ private:
llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
UsesAllocatorsDecls;
+ Expr *DeclareMapperVar = nullptr;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
: Directive(DKind), DirectiveName(Name), CurScope(CurScope),
@@ -510,7 +519,8 @@ public:
/// Adds explicit data sharing attribute to the specified declaration.
void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
- DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0);
+ DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
+ bool AppliedToPointee = false);
/// Adds additional information for the reduction items with the reduction id
/// represented as an operator.
@@ -562,7 +572,8 @@ public:
/// match specified \a CPred predicate in any directive which matches \a DPred
/// predicate.
const DSAVarData
- hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
+ hasDSA(ValueDecl *D,
+ const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
bool FromParent) const;
/// Checks if the specified variables has data-sharing attributes which
@@ -570,15 +581,16 @@ public:
/// matches \a DPred predicate.
const DSAVarData
hasInnermostDSA(ValueDecl *D,
- const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
+ const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
bool FromParent) const;
/// Checks if the specified variables has explicit data-sharing
/// attributes which match specified \a CPred predicate at the specified
/// OpenMP region.
- bool hasExplicitDSA(const ValueDecl *D,
- const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
- unsigned Level, bool NotLastprivate = false) const;
+ bool
+ hasExplicitDSA(const ValueDecl *D,
+ const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
+ unsigned Level, bool NotLastprivate = false) const;
/// Returns true if the directive at level \Level matches in the
/// specified \a DPred predicate.
@@ -908,6 +920,7 @@ public:
const SharingMapTy *Top = getTopOfStackOrNull();
return Top ? Top->CurScope : nullptr;
}
+ void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
SourceLocation getConstructLoc() const {
const SharingMapTy *Top = getTopOfStackOrNull();
return Top ? Top->ConstructLoc : SourceLocation();
@@ -1072,6 +1085,15 @@ public:
return None;
return I->getSecond();
}
+
+ void addDeclareMapperVarRef(Expr *Ref) {
+ SharingMapTy &StackElem = getTopOfStack();
+ StackElem.DeclareMapperVar = Ref;
+ }
+ const Expr *getDeclareMapperVarRef() const {
+ const SharingMapTy *Top = getTopOfStackOrNull();
+ return Top ? Top->DeclareMapperVar : nullptr;
+ }
};
bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
@@ -1175,6 +1197,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
DVar.CKind = Data.Attributes;
DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
DVar.Modifier = Data.Modifier;
+ DVar.AppliedToPointee = Data.AppliedToPointee;
return DVar;
}
@@ -1331,7 +1354,8 @@ const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
}
void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
- DeclRefExpr *PrivateCopy, unsigned Modifier) {
+ DeclRefExpr *PrivateCopy, unsigned Modifier,
+ bool AppliedToPointee) {
D = getCanonicalDecl(D);
if (A == OMPC_threadprivate) {
DSAInfo &Data = Threadprivates[D];
@@ -1355,12 +1379,14 @@ void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
Data.Attributes = A;
Data.RefExpr.setPointerAndInt(E, IsLastprivate);
Data.PrivateCopy = PrivateCopy;
+ Data.AppliedToPointee = AppliedToPointee;
if (PrivateCopy) {
DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
Data.Modifier = Modifier;
Data.Attributes = A;
Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
Data.PrivateCopy = nullptr;
+ Data.AppliedToPointee = AppliedToPointee;
}
}
}
@@ -1470,7 +1496,8 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
"set.");
TaskgroupDescriptor = I->TaskgroupReductionRef;
return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
- Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task);
+ Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
+ /*AppliedToPointee=*/false);
}
return DSAVarData();
}
@@ -1496,7 +1523,8 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
"set.");
TaskgroupDescriptor = I->TaskgroupReductionRef;
return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
- Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task);
+ Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
+ /*AppliedToPointee=*/false);
}
return DSAVarData();
}
@@ -1506,11 +1534,17 @@ bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
for (const_iterator E = end(); I != E; ++I) {
if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
isOpenMPTargetExecutionDirective(I->Directive)) {
- Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
- Scope *CurScope = getCurScope();
- while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
- CurScope = CurScope->getParent();
- return CurScope != TopScope;
+ if (I->CurScope) {
+ Scope *TopScope = I->CurScope->getParent();
+ Scope *CurScope = getCurScope();
+ while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
+ CurScope = CurScope->getParent();
+ return CurScope != TopScope;
+ }
+ for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
+ if (I->Context == DC)
+ return true;
+ return false;
}
}
return false;
@@ -1665,6 +1699,7 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
DVar.ImplicitDSALoc = I->DefaultAttrLoc;
DVar.DKind = I->Directive;
DVar.Modifier = Data.Modifier;
+ DVar.AppliedToPointee = Data.AppliedToPointee;
return DVar;
}
}
@@ -1686,7 +1721,7 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
// listed in a firstprivate clause, even if they are static data members.
DSAVarData DVarTemp = hasInnermostDSA(
D,
- [](OpenMPClauseKind C) {
+ [](OpenMPClauseKind C, bool) {
return C == OMPC_firstprivate || C == OMPC_shared;
},
MatchesAlways, FromParent);
@@ -1715,6 +1750,7 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
DVar.ImplicitDSALoc = I->DefaultAttrLoc;
DVar.DKind = I->Directive;
DVar.Modifier = Data.Modifier;
+ DVar.AppliedToPointee = Data.AppliedToPointee;
}
return DVar;
@@ -1745,7 +1781,7 @@ const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
const DSAStackTy::DSAVarData
DSAStackTy::hasDSA(ValueDecl *D,
- const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
+ const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
bool FromParent) const {
if (isStackEmpty())
@@ -1761,14 +1797,14 @@ DSAStackTy::hasDSA(ValueDecl *D,
continue;
const_iterator NewI = I;
DSAVarData DVar = getDSA(NewI, D);
- if (I == NewI && CPred(DVar.CKind))
+ if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
return DVar;
}
return {};
}
const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
- ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
+ ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
bool FromParent) const {
if (isStackEmpty())
@@ -1782,26 +1818,28 @@ const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
return {};
const_iterator NewI = StartI;
DSAVarData DVar = getDSA(NewI, D);
- return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
+ return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
+ ? DVar
+ : DSAVarData();
}
bool DSAStackTy::hasExplicitDSA(
- const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
+ const ValueDecl *D,
+ const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
unsigned Level, bool NotLastprivate) const {
if (getStackSize() <= Level)
return false;
D = getCanonicalDecl(D);
const SharingMapTy &StackElem = getStackElemAtLevel(Level);
auto I = StackElem.SharingMap.find(D);
- if (I != StackElem.SharingMap.end() &&
- I->getSecond().RefExpr.getPointer() &&
- CPred(I->getSecond().Attributes) &&
+ if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
+ CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
(!NotLastprivate || !I->getSecond().RefExpr.getInt()))
return true;
// Check predetermined rules for the loop control variables.
auto LI = StackElem.LCVMap.find(D);
if (LI != StackElem.LCVMap.end())
- return CPred(OMPC_private);
+ return CPred(OMPC_private, /*AppliedToPointee=*/false);
return false;
}
@@ -1859,27 +1897,27 @@ enum class FunctionEmissionStatus {
};
} // anonymous namespace
-Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
- unsigned DiagID) {
+Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
+ unsigned DiagID) {
assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.");
FunctionDecl *FD = getCurFunctionDecl();
- DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
+ SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
if (FD) {
FunctionEmissionStatus FES = getEmissionStatus(FD);
switch (FES) {
case FunctionEmissionStatus::Emitted:
- Kind = DeviceDiagBuilder::K_Immediate;
+ Kind = SemaDiagnosticBuilder::K_Immediate;
break;
case FunctionEmissionStatus::Unknown:
Kind = isOpenMPDeviceDelayedContext(*this)
- ? DeviceDiagBuilder::K_Deferred
- : DeviceDiagBuilder::K_Immediate;
+ ? SemaDiagnosticBuilder::K_Deferred
+ : SemaDiagnosticBuilder::K_Immediate;
break;
case FunctionEmissionStatus::TemplateDiscarded:
case FunctionEmissionStatus::OMPDiscarded:
- Kind = DeviceDiagBuilder::K_Nop;
+ Kind = SemaDiagnosticBuilder::K_Nop;
break;
case FunctionEmissionStatus::CUDADiscarded:
llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
@@ -1887,30 +1925,30 @@ Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
}
}
- return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
+ return SemaDiagnosticBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
}
-Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
- unsigned DiagID) {
+Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
+ unsigned DiagID) {
assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
"Expected OpenMP host compilation.");
FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
- DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
+ SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
switch (FES) {
case FunctionEmissionStatus::Emitted:
- Kind = DeviceDiagBuilder::K_Immediate;
+ Kind = SemaDiagnosticBuilder::K_Immediate;
break;
case FunctionEmissionStatus::Unknown:
- Kind = DeviceDiagBuilder::K_Deferred;
+ Kind = SemaDiagnosticBuilder::K_Deferred;
break;
case FunctionEmissionStatus::TemplateDiscarded:
case FunctionEmissionStatus::OMPDiscarded:
case FunctionEmissionStatus::CUDADiscarded:
- Kind = DeviceDiagBuilder::K_Nop;
+ Kind = SemaDiagnosticBuilder::K_Nop;
break;
}
- return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
+ return SemaDiagnosticBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
}
static OpenMPDefaultmapClauseKind
@@ -2047,14 +2085,17 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
// By default, all the data that has a scalar type is mapped by copy
// (except for reduction variables).
// Defaultmap scalar is mutual exclusive to defaultmap pointer
- IsByRef =
- (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
- !Ty->isAnyPointerType()) ||
- !Ty->isScalarType() ||
- DSAStack->isDefaultmapCapturedByRef(
- Level, getVariableCategoryFromDecl(LangOpts, D)) ||
- DSAStack->hasExplicitDSA(
- D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
+ IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
+ !Ty->isAnyPointerType()) ||
+ !Ty->isScalarType() ||
+ DSAStack->isDefaultmapCapturedByRef(
+ Level, getVariableCategoryFromDecl(LangOpts, D)) ||
+ DSAStack->hasExplicitDSA(
+ D,
+ [](OpenMPClauseKind K, bool AppliedToPointee) {
+ return K == OMPC_reduction && !AppliedToPointee;
+ },
+ Level);
}
}
@@ -2065,8 +2106,9 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
OMPD_target) ||
!(DSAStack->hasExplicitDSA(
D,
- [](OpenMPClauseKind K) -> bool {
- return K == OMPC_firstprivate;
+ [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
+ return K == OMPC_firstprivate ||
+ (K == OMPC_reduction && AppliedToPointee);
},
Level, /*NotLastprivate=*/true) ||
DSAStack->isUsesAllocatorsDecl(Level, D))) &&
@@ -2078,7 +2120,8 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
// copy
!(DSAStack->getDefaultDSA() == DSA_firstprivate &&
!DSAStack->hasExplicitDSA(
- D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) &&
+ D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
+ Level) &&
!DSAStack->isLoopControlVariable(D, Level).first);
}
@@ -2141,7 +2184,8 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
return nullptr;
- } else if (isInOpenMPTargetExecutionDirective()) {
+ }
+ if (isInOpenMPTargetExecutionDirective()) {
// If the declaration is enclosed in a 'declare target' directive,
// then it should not be captured.
//
@@ -2159,6 +2203,7 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
break;
}
}
+ assert(CSI && "Failed to find CapturedRegionScopeInfo");
SmallVector<OpenMPDirectiveKind, 4> Regions;
getOpenMPCaptureRegions(Regions,
DSAStack->getDirective(CSI->OpenMPLevel));
@@ -2194,7 +2239,8 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
return VD ? VD : Info.second;
DSAStackTy::DSAVarData DVarTop =
DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
- if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind))
+ if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
+ (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
// Threadprivate variables must not be captured.
if (isOpenMPThreadPrivate(DVarTop.CKind))
@@ -2202,7 +2248,11 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
// The variable is not private or it is the variable in the directive with
// default(none) clause and not used in any clause.
DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
- D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
+ D,
+ [](OpenMPClauseKind C, bool AppliedToPointee) {
+ return isOpenMPPrivate(C) && !AppliedToPointee;
+ },
+ [](OpenMPDirectiveKind) { return true; },
DSAStack->isClauseParsingMode());
// Global shared must not be captured.
if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
@@ -2244,7 +2294,11 @@ OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
[](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
Level)) {
bool IsTriviallyCopyable =
- D->getType().getNonReferenceType().isTriviallyCopyableType(Context);
+ D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
+ !D->getType()
+ .getNonReferenceType()
+ .getCanonicalType()
+ ->getAsCXXRecordDecl();
OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
getOpenMPCaptureRegions(CaptureRegions, DKind);
@@ -2252,7 +2306,8 @@ OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
(IsTriviallyCopyable ||
!isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
if (DSAStack->hasExplicitDSA(
- D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; },
+ D,
+ [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
Level, /*NotLastprivate=*/true))
return OMPC_firstprivate;
DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
@@ -2273,7 +2328,8 @@ OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
DSAStack->isLoopControlVariable(D).first) &&
!DSAStack->hasExplicitDSA(
- D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
+ D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
+ Level) &&
!isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
return OMPC_private;
}
@@ -2281,7 +2337,8 @@ OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
DSAStack->isForceVarCapturing() &&
!DSAStack->hasExplicitDSA(
- D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level))
+ D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
+ Level))
return OMPC_private;
}
// User-defined allocators are private since they must be defined in the
@@ -2292,7 +2349,8 @@ OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
return OMPC_private;
return (DSAStack->hasExplicitDSA(
- D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
+ D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
+ Level) ||
(DSAStack->isClauseParsingMode() &&
DSAStack->getClauseParsingMode() == OMPC_private) ||
// Consider taskgroup reduction descriptor variable a private
@@ -2317,15 +2375,16 @@ void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
OpenMPClauseKind OMPC = OMPC_unknown;
for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
const unsigned NewLevel = I - 1;
- if (DSAStack->hasExplicitDSA(D,
- [&OMPC](const OpenMPClauseKind K) {
- if (isOpenMPPrivate(K)) {
- OMPC = K;
- return true;
- }
- return false;
- },
- NewLevel))
+ if (DSAStack->hasExplicitDSA(
+ D,
+ [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
+ if (isOpenMPPrivate(K) && !AppliedToPointee) {
+ OMPC = K;
+ return true;
+ }
+ return false;
+ },
+ NewLevel))
break;
if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
D, NewLevel,
@@ -2368,17 +2427,20 @@ bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (!VD->hasLocalStorage()) {
+ if (isInOpenMPTargetExecutionDirective())
+ return true;
DSAStackTy::DSAVarData TopDVar =
DSAStack->getTopDSA(D, /*FromParent=*/false);
unsigned NumLevels =
getOpenMPCaptureLevels(DSAStack->getDirective(Level));
if (Level == 0)
return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
- DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1);
- return DVar.CKind != OMPC_shared ||
- isOpenMPGlobalCapturedDecl(
- D, Level - 1,
- getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1);
+ do {
+ --Level;
+ DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
+ if (DVar.CKind != OMPC_shared)
+ return true;
+ } while (Level > 0);
}
}
return true;
@@ -2388,10 +2450,6 @@ void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
OMPTraitInfo &TI) {
- if (!OMPDeclareVariantScopes.empty()) {
- Diag(Loc, diag::warn_nested_declare_variant);
- return;
- }
OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
}
@@ -2424,7 +2482,7 @@ void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
StringRef HostDevTy =
getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
- Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
+ Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
diag::note_omp_marked_device_type_here)
<< HostDevTy;
return;
@@ -2435,7 +2493,7 @@ void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
- Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
+ Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
diag::note_omp_marked_device_type_here)
<< NoHostDevTy;
}
@@ -3138,6 +3196,64 @@ Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
return DeclGroupPtrTy::make(DeclGroupRef(D));
}
+void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
+ OpenMPDirectiveKind DKind,
+ ArrayRef<StringRef> Assumptions,
+ bool SkippedClauses) {
+ if (!SkippedClauses && Assumptions.empty())
+ Diag(Loc, diag::err_omp_no_clause_for_directive)
+ << llvm::omp::getAllAssumeClauseOptions()
+ << llvm::omp::getOpenMPDirectiveName(DKind);
+
+ auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
+ if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
+ OMPAssumeScoped.push_back(AA);
+ return;
+ }
+
+ // Global assumes without assumption clauses are ignored.
+ if (Assumptions.empty())
+ return;
+
+ assert(DKind == llvm::omp::Directive::OMPD_assumes &&
+ "Unexpected omp assumption directive!");
+ OMPAssumeGlobal.push_back(AA);
+
+ // The OMPAssumeGlobal scope above will take care of new declarations but
+ // we also want to apply the assumption to existing ones, e.g., to
+ // declarations in included headers. To this end, we traverse all existing
+ // declaration contexts and annotate function declarations here.
+ SmallVector<DeclContext *, 8> DeclContexts;
+ auto *Ctx = CurContext;
+ while (Ctx->getLexicalParent())
+ Ctx = Ctx->getLexicalParent();
+ DeclContexts.push_back(Ctx);
+ while (!DeclContexts.empty()) {
+ DeclContext *DC = DeclContexts.pop_back_val();
+ for (auto *SubDC : DC->decls()) {
+ if (SubDC->isInvalidDecl())
+ continue;
+ if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
+ DeclContexts.push_back(CTD->getTemplatedDecl());
+ for (auto *S : CTD->specializations())
+ DeclContexts.push_back(S);
+ continue;
+ }
+ if (auto *DC = dyn_cast<DeclContext>(SubDC))
+ DeclContexts.push_back(DC);
+ if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
+ F->addAttr(AA);
+ continue;
+ }
+ }
+ }
+}
+
+void Sema::ActOnOpenMPEndAssumesDirective() {
+ assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
+ OMPAssumeScoped.pop_back();
+}
+
OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
ArrayRef<OMPClause *> ClauseList) {
/// For target specific clauses, the requires directive cannot be
@@ -3249,6 +3365,14 @@ getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
case OMPC_DEFAULTMAP_MODIFIER_tofrom:
Kind = OMPC_MAP_tofrom;
break;
+ case OMPC_DEFAULTMAP_MODIFIER_present:
+ // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
+ // If implicit-behavior is present, each variable referenced in the
+ // construct in the category specified by variable-category is treated as if
+ // it had been listed in a map clause with the map-type of alloc and
+ // map-type-modifier of present.
+ Kind = OMPC_MAP_alloc;
+ break;
case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
case OMPC_DEFAULTMAP_MODIFIER_last:
llvm_unreachable("Unexpected defaultmap implicit behavior");
@@ -3275,8 +3399,11 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
bool ErrorFound = false;
bool TryCaptureCXXThisMembers = false;
CapturedStmt *CS = nullptr;
+ const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
- llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
+ llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
+ llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
+ ImplicitMapModifier[DefaultmapKindNum];
Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
@@ -3284,6 +3411,13 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
// Check implicitly captured variables.
if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
return;
+ if (S->getDirectiveKind() == OMPD_atomic ||
+ S->getDirectiveKind() == OMPD_critical ||
+ S->getDirectiveKind() == OMPD_section ||
+ S->getDirectiveKind() == OMPD_master) {
+ Visit(S->getAssociatedStmt());
+ return;
+ }
visitSubCaptures(S->getInnermostCapturedStmt());
// Try to capture inner this->member references to generate correct mappings
// and diagnostics.
@@ -3405,6 +3539,18 @@ public:
}
}
}
+ if (SemaRef.getLangOpts().OpenMP > 50) {
+ bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
+ OMPC_DEFAULTMAP_MODIFIER_present;
+ if (IsModifierPresent) {
+ if (llvm::find(ImplicitMapModifier[ClauseKind],
+ OMPC_MAP_MODIFIER_present) ==
+ std::end(ImplicitMapModifier[ClauseKind])) {
+ ImplicitMapModifier[ClauseKind].push_back(
+ OMPC_MAP_MODIFIER_present);
+ }
+ }
+ }
if (isOpenMPTargetExecutionDirective(DKind) &&
!Stack->isLoopControlVariable(VD).first) {
@@ -3445,7 +3591,7 @@ public:
Stack->getDefaultmapModifier(ClauseKind);
OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
- ImplicitMap[Kind].emplace_back(E);
+ ImplicitMap[ClauseKind][Kind].emplace_back(E);
}
return;
}
@@ -3456,7 +3602,10 @@ public:
// enclosing worksharing or parallel construct may not be accessed in an
// explicit task.
DVar = Stack->hasInnermostDSA(
- VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
+ VD,
+ [](OpenMPClauseKind C, bool AppliedToPointee) {
+ return C == OMPC_reduction && !AppliedToPointee;
+ },
[](OpenMPDirectiveKind K) {
return isOpenMPParallelDirective(K) ||
isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
@@ -3529,9 +3678,11 @@ public:
OpenMPDefaultmapClauseModifier Modifier =
Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
+ OpenMPDefaultmapClauseKind ClauseKind =
+ getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
Modifier, /*IsAggregateOrDeclareTarget*/ true);
- ImplicitMap[Kind].emplace_back(E);
+ ImplicitMap[ClauseKind][Kind].emplace_back(E);
return;
}
@@ -3541,7 +3692,10 @@ public:
// enclosing worksharing or parallel construct may not be accessed in
// an explicit task.
DVar = Stack->hasInnermostDSA(
- FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
+ FD,
+ [](OpenMPClauseKind C, bool AppliedToPointee) {
+ return C == OMPC_reduction && !AppliedToPointee;
+ },
[](OpenMPDirectiveKind K) {
return isOpenMPParallelDirective(K) ||
isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
@@ -3570,6 +3724,7 @@ public:
if (isOpenMPTargetExecutionDirective(DKind)) {
OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
+ Stack->getCurrentDirective(),
/*NoDiagnose=*/true))
return;
const auto *VD = cast<ValueDecl>(
@@ -3619,7 +3774,8 @@ public:
// Skip analysis of arguments of implicitly defined map clause for target
// directives.
if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
- C->isImplicit())) {
+ C->isImplicit() &&
+ !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
for (Stmt *CC : C->children()) {
if (CC)
Visit(CC);
@@ -3662,8 +3818,13 @@ public:
ArrayRef<Expr *> getImplicitFirstprivate() const {
return ImplicitFirstprivate;
}
- ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
- return ImplicitMap[Kind];
+ ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
+ OpenMPMapClauseKind MK) const {
+ return ImplicitMap[DK][MK];
+ }
+ ArrayRef<OpenMPMapModifierKind>
+ getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
+ return ImplicitMapModifier[Kind];
}
const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
return VarsWithInheritedDSA;
@@ -3784,19 +3945,20 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
/*OpenMPCaptureLevel=*/1);
break;
}
+ case OMPD_atomic:
+ case OMPD_critical:
+ case OMPD_section:
+ case OMPD_master:
+ break;
case OMPD_simd:
case OMPD_for:
case OMPD_for_simd:
case OMPD_sections:
- case OMPD_section:
case OMPD_single:
- case OMPD_master:
- case OMPD_critical:
case OMPD_taskgroup:
case OMPD_distribute:
case OMPD_distribute_simd:
case OMPD_ordered:
- case OMPD_atomic:
case OMPD_target_data: {
Sema::CapturedParamNameType Params[] = {
std::make_pair(StringRef(), QualType()) // __context with shared vars
@@ -4088,6 +4250,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
default:
llvm_unreachable("Unknown OpenMP directive");
}
+ DSAStack->setContext(CurContext);
}
int Sema::getNumberOfConstructScopes(unsigned Level) const {
@@ -4125,6 +4288,7 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
if (!WithInit)
CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
S.CurContext->addHiddenDecl(CED);
+ Sema::TentativeAnalysisScope Trap(S);
S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
return CED;
}
@@ -4262,6 +4426,12 @@ static bool checkOrderedOrderSpecified(Sema &S,
StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
ArrayRef<OMPClause *> Clauses) {
+ if (DSAStack->getCurrentDirective() == OMPD_atomic ||
+ DSAStack->getCurrentDirective() == OMPD_critical ||
+ DSAStack->getCurrentDirective() == OMPD_section ||
+ DSAStack->getCurrentDirective() == OMPD_master)
+ return S;
+
bool ErrorFound = false;
CaptureRegionUnwinderRAII CaptureRegionUnwinder(
*this, ErrorFound, DSAStack->getCurrentDirective());
@@ -4975,7 +5145,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
VarsWithInheritedDSAType VarsWithInheritedDSA;
bool ErrorFound = false;
ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
- if (AStmt && !CurContext->isDependentContext()) {
+ if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
+ Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) {
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
// Check default data sharing attributes for referenced variables.
@@ -5004,11 +5175,33 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
SmallVector<Expr *, 4> ImplicitFirstprivates(
DSAChecker.getImplicitFirstprivate().begin(),
DSAChecker.getImplicitFirstprivate().end());
- SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
- for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
- ArrayRef<Expr *> ImplicitMap =
- DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
- ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
+ const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
+ SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
+ SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
+ ImplicitMapModifiers[DefaultmapKindNum];
+ SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
+ ImplicitMapModifiersLoc[DefaultmapKindNum];
+ // Get the original location of present modifier from Defaultmap clause.
+ SourceLocation PresentModifierLocs[DefaultmapKindNum];
+ for (OMPClause *C : Clauses) {
+ if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
+ if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
+ PresentModifierLocs[DMC->getDefaultmapKind()] =
+ DMC->getDefaultmapModifierLoc();
+ }
+ for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
+ auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
+ for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
+ ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
+ Kind, static_cast<OpenMPMapClauseKind>(I));
+ ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
+ }
+ ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
+ DSAChecker.getImplicitMapModifier(Kind);
+ ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
+ ImplicitModifier.end());
+ std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
+ ImplicitModifier.size(), PresentModifierLocs[VC]);
}
// Mark taskgroup task_reduction descriptors as implicitly firstprivate.
for (OMPClause *C : Clauses) {
@@ -5034,23 +5227,26 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
ErrorFound = true;
}
}
- int ClauseKindCnt = -1;
- for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
- ++ClauseKindCnt;
- if (ImplicitMap.empty())
- continue;
- CXXScopeSpec MapperIdScopeSpec;
- DeclarationNameInfo MapperId;
- auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
- if (OMPClause *Implicit = ActOnOpenMPMapClause(
- llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
- /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
- ImplicitMap, OMPVarListLocTy())) {
- ClausesWithImplicit.emplace_back(Implicit);
- ErrorFound |=
- cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
- } else {
- ErrorFound = true;
+ for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
+ int ClauseKindCnt = -1;
+ for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
+ ++ClauseKindCnt;
+ if (ImplicitMap.empty())
+ continue;
+ CXXScopeSpec MapperIdScopeSpec;
+ DeclarationNameInfo MapperId;
+ auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
+ if (OMPClause *Implicit = ActOnOpenMPMapClause(
+ ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
+ MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
+ SourceLocation(), SourceLocation(), ImplicitMap,
+ OMPVarListLocTy())) {
+ ClausesWithImplicit.emplace_back(Implicit);
+ ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
+ ImplicitMap.size();
+ } else {
+ ErrorFound = true;
+ }
}
}
}
@@ -5760,7 +5956,8 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
.get();
if (NewStep)
- NewStep = VerifyIntegerConstantExpression(NewStep).get();
+ NewStep =
+ VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
}
NewSteps.push_back(NewStep);
}
@@ -5798,12 +5995,45 @@ static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
FD->setParams(Params);
}
+void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
+ if (D->isInvalidDecl())
+ return;
+ FunctionDecl *FD = nullptr;
+ if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
+ FD = UTemplDecl->getTemplatedDecl();
+ else
+ FD = cast<FunctionDecl>(D);
+ assert(FD && "Expected a function declaration!");
+
+ // If we are intantiating templates we do *not* apply scoped assumptions but
+ // only global ones. We apply scoped assumption to the template definition
+ // though.
+ if (!inTemplateInstantiation()) {
+ for (AssumptionAttr *AA : OMPAssumeScoped)
+ FD->addAttr(AA);
+ }
+ for (AssumptionAttr *AA : OMPAssumeGlobal)
+ FD->addAttr(AA);
+}
+
Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
: TI(&TI), NameSuffix(TI.getMangledName()) {}
-FunctionDecl *
-Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S,
- Declarator &D) {
+void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
+ Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
+ SmallVectorImpl<FunctionDecl *> &Bases) {
+ if (!D.getIdentifier())
+ return;
+
+ OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
+
+ // Template specialization is an extension, check if we do it.
+ bool IsTemplated = !TemplateParamLists.empty();
+ if (IsTemplated &
+ !DVScope.TI->isExtensionActive(
+ llvm::omp::TraitProperty::implementation_extension_allow_templates))
+ return;
+
IdentifierInfo *BaseII = D.getIdentifier();
LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
LookupOrdinaryName);
@@ -5812,12 +6042,18 @@ Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S,
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
QualType FType = TInfo->getType();
- bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr;
- bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval;
+ bool IsConstexpr =
+ D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
+ bool IsConsteval =
+ D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
- FunctionDecl *BaseFD = nullptr;
for (auto *Candidate : Lookup) {
- auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl());
+ auto *CandidateDecl = Candidate->getUnderlyingDecl();
+ FunctionDecl *UDecl = nullptr;
+ if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
+ UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
+ else if (!IsTemplated)
+ UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
if (!UDecl)
continue;
@@ -5828,22 +6064,32 @@ Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S,
if (UDecl->isConsteval() && !IsConsteval)
continue;
- QualType NewType = Context.mergeFunctionTypes(
- FType, UDecl->getType(), /* OfBlockPointer */ false,
- /* Unqualified */ false, /* AllowCXX */ true);
- if (NewType.isNull())
- continue;
+ QualType UDeclTy = UDecl->getType();
+ if (!UDeclTy->isDependentType()) {
+ QualType NewType = Context.mergeFunctionTypes(
+ FType, UDeclTy, /* OfBlockPointer */ false,
+ /* Unqualified */ false, /* AllowCXX */ true);
+ if (NewType.isNull())
+ continue;
+ }
// Found a base!
- BaseFD = UDecl;
- break;
- }
- if (!BaseFD) {
- BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D));
- BaseFD->setImplicit(true);
+ Bases.push_back(UDecl);
+ }
+
+ bool UseImplicitBase = !DVScope.TI->isExtensionActive(
+ llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
+ // If no base was found we create a declaration that we use as base.
+ if (Bases.empty() && UseImplicitBase) {
+ D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
+ Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
+ BaseD->setImplicit(true);
+ if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
+ Bases.push_back(BaseTemplD->getTemplatedDecl());
+ else
+ Bases.push_back(cast<FunctionDecl>(BaseD));
}
- OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
std::string MangledName;
MangledName += D.getIdentifier()->getName();
MangledName += getOpenMPVariantManglingSeparatorStr();
@@ -5852,17 +6098,21 @@ Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S,
VariantII.setMangledOpenMPVariantName(true);
D.SetIdentifier(&VariantII, D.getBeginLoc());
- return BaseFD;
}
void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
- FunctionDecl *FD, FunctionDecl *BaseFD) {
+ Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
// Do not mark function as is used to prevent its emission if this is the
// only place where it is used.
EnterExpressionEvaluationContext Unevaluated(
*this, Sema::ExpressionEvaluationContext::Unevaluated);
- Expr *VariantFuncRef = DeclRefExpr::Create(
+ FunctionDecl *FD = nullptr;
+ if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
+ FD = UTemplDecl->getTemplatedDecl();
+ else
+ FD = cast<FunctionDecl>(D);
+ auto *VariantFuncRef = DeclRefExpr::Create(
Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
/* RefersToEnclosingVariableOrCapture */ false,
/* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
@@ -5870,7 +6120,8 @@ void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
Context, VariantFuncRef, DVScope.TI);
- BaseFD->addAttr(OMPDeclareVariantA);
+ for (FunctionDecl *BaseFD : Bases)
+ BaseFD->addAttr(OMPDeclareVariantA);
}
ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
@@ -5891,8 +6142,17 @@ ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
return Call;
ASTContext &Context = getASTContext();
- OMPContext OMPCtx(getLangOpts().OpenMPIsDevice,
- Context.getTargetInfo().getTriple());
+ std::function<void(StringRef)> DiagUnknownTrait = [this,
+ CE](StringRef ISATrait) {
+ // TODO Track the selector locations in a way that is accessible here to
+ // improve the diagnostic location.
+ Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
+ << ISATrait;
+ };
+ TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
+ getCurFunctionDecl());
+
+ QualType CalleeFnType = CalleeFnDecl->getType();
SmallVector<Expr *, 4> Exprs;
SmallVector<VariantMatchInfo, 4> VMIs;
@@ -5904,7 +6164,8 @@ ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
VariantMatchInfo VMI;
OMPTraitInfo &TI = A->getTraitInfo();
TI.getAsVariantMatchInfo(Context, VMI);
- if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false))
+ if (!isVariantApplicableInContext(VMI, OMPCtx,
+ /* DeviceSetOnly */ false))
continue;
VMIs.push_back(VMI);
@@ -5945,8 +6206,19 @@ ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
}
NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
ExecConfig);
- if (NewCall.isUsable())
- break;
+ if (NewCall.isUsable()) {
+ if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
+ FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
+ QualType NewType = Context.mergeFunctionTypes(
+ CalleeFnType, NewCalleeFnDecl->getType(),
+ /* OfBlockPointer */ false,
+ /* Unqualified */ false, /* AllowCXX */ true);
+ if (!NewType.isNull())
+ break;
+ // Don't use the call if the function type was not compatible.
+ NewCall = nullptr;
+ }
+ }
}
VMIs.erase(VMIs.begin() + BestIdx);
@@ -6027,8 +6299,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
// Deal with non-constant score and user condition expressions.
auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
bool IsScore) -> bool {
- llvm::APSInt Result;
- if (!E || E->isIntegerConstantExpr(Result, Context))
+ if (!E || E->isIntegerConstantExpr(Context))
return false;
if (IsScore) {
@@ -6051,7 +6322,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
// Convert VariantRef expression to the type of the original function to
// resolve possible conflicts.
- ExprResult VariantRefCast;
+ ExprResult VariantRefCast = VariantRef;
if (LangOpts.CPlusPlus) {
QualType FnPtrType;
auto *Method = dyn_cast<CXXMethodDecl>(FD);
@@ -6076,25 +6347,27 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
} else {
FnPtrType = Context.getPointerType(FD->getType());
}
- ImplicitConversionSequence ICS =
- TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
- /*SuppressUserConversions=*/false,
- AllowedExplicit::None,
- /*InOverloadResolution=*/false,
- /*CStyle=*/false,
- /*AllowObjCWritebackConversion=*/false);
- if (ICS.isFailure()) {
- Diag(VariantRef->getExprLoc(),
- diag::err_omp_declare_variant_incompat_types)
- << VariantRef->getType()
- << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
- << VariantRef->getSourceRange();
- return None;
+ QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
+ if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
+ ImplicitConversionSequence ICS = TryImplicitConversion(
+ VariantRef, FnPtrType.getUnqualifiedType(),
+ /*SuppressUserConversions=*/false, AllowedExplicit::None,
+ /*InOverloadResolution=*/false,
+ /*CStyle=*/false,
+ /*AllowObjCWritebackConversion=*/false);
+ if (ICS.isFailure()) {
+ Diag(VariantRef->getExprLoc(),
+ diag::err_omp_declare_variant_incompat_types)
+ << VariantRef->getType()
+ << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
+ << VariantRef->getSourceRange();
+ return None;
+ }
+ VariantRefCast = PerformImplicitConversion(
+ VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
+ if (!VariantRefCast.isUsable())
+ return None;
}
- VariantRefCast = PerformImplicitConversion(
- VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
- if (!VariantRefCast.isUsable())
- return None;
// Drop previously built artificial addr_of unary op for member functions.
if (Method && !Method->isStatic()) {
Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
@@ -6102,8 +6375,6 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
PossibleAddrOfVariantRef->IgnoreImplicit()))
VariantRefCast = UO->getSubExpr();
}
- } else {
- VariantRefCast = VariantRef;
}
ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
@@ -6514,14 +6785,14 @@ bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
// loop. If test-expr is of form b relational-op var and relational-op is
// > or >= then incr-expr must cause var to increase on each iteration of
// the loop.
- llvm::APSInt Result;
- bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
+ Optional<llvm::APSInt> Result =
+ NewStep->getIntegerConstantExpr(SemaRef.Context);
bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
bool IsConstNeg =
- IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
+ Result && Result->isSigned() && (Subtract != Result->isNegative());
bool IsConstPos =
- IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
- bool IsConstZero = IsConstant && !Result.getBoolValue();
+ Result && Result->isSigned() && (Subtract == Result->isNegative());
+ bool IsConstZero = Result && !Result->getBoolValue();
// != with increment is treated as <; != with decrement is treated as >
if (!TestIsLessOp.hasValue())
@@ -6969,9 +7240,16 @@ calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
if (!NewStep.isUsable())
return nullptr;
- llvm::APSInt LRes, URes, SRes;
- bool IsLowerConst = Lower->isIntegerConstantExpr(LRes, SemaRef.Context);
- bool IsStepConst = Step->isIntegerConstantExpr(SRes, SemaRef.Context);
+ llvm::APSInt LRes, SRes;
+ bool IsLowerConst = false, IsStepConst = false;
+ if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
+ LRes = *Res;
+ IsLowerConst = true;
+ }
+ if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
+ SRes = *Res;
+ IsStepConst = true;
+ }
bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
((!TestIsStrictOp && LRes.isNonNegative()) ||
(TestIsStrictOp && LRes.isStrictlyPositive()));
@@ -7004,7 +7282,12 @@ calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
}
NeedToReorganize = NoNeedToConvert;
}
- bool IsUpperConst = Upper->isIntegerConstantExpr(URes, SemaRef.Context);
+ llvm::APSInt URes;
+ bool IsUpperConst = false;
+ if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
+ URes = *Res;
+ IsUpperConst = true;
+ }
if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
(!RoundToStep || IsStepConst)) {
unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
@@ -7436,6 +7719,7 @@ std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
if (!Diff.isUsable())
return std::make_pair(nullptr, nullptr);
+ Sema::TentativeAnalysisScope Trap(SemaRef);
Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
if (!Diff.isUsable())
return std::make_pair(nullptr, nullptr);
@@ -7952,9 +8236,9 @@ static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
if (E == nullptr)
return false;
- llvm::APSInt Result;
- if (E->isIntegerConstantExpr(Result, SemaRef.Context))
- return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
+ if (Optional<llvm::APSInt> Result =
+ E->getIntegerConstantExpr(SemaRef.Context))
+ return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
return false;
}
@@ -8227,9 +8511,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// Calculate the last iteration number beforehand instead of doing this on
// each iteration. Do not do this if the number of iterations may be kfold-ed.
- llvm::APSInt Result;
- bool IsConstant =
- LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
+ bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
ExprResult CalcLastIteration;
if (!IsConstant) {
ExprResult SaveRef =
@@ -8915,8 +9197,6 @@ StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
if (!AStmt)
return StmtError();
- assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
-
setFunctionHasBranchProtectedScope();
DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
@@ -8961,8 +9241,6 @@ StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
if (!AStmt)
return StmtError();
- assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
-
setFunctionHasBranchProtectedScope();
return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
@@ -8974,8 +9252,6 @@ StmtResult Sema::ActOnOpenMPCriticalDirective(
if (!AStmt)
return StmtError();
- assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
-
bool ErrorFound = false;
llvm::APSInt Hint;
SourceLocation HintLoc;
@@ -9693,7 +9969,6 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
if (!AStmt)
return StmtError();
- auto *CS = cast<CapturedStmt>(AStmt);
// 1.2.2 OpenMP Language Terminology
// Structured block - An executable statement with a single entry at the
// top and a single exit at the bottom.
@@ -9757,7 +10032,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
<< getOpenMPClauseName(MemOrderKind);
}
- Stmt *Body = CS->getCapturedStmt();
+ Stmt *Body = AStmt;
if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
Body = EWC->getSubExpr();
@@ -12620,15 +12895,16 @@ isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
ValExpr = Value.get();
// The expression must evaluate to a non-negative integer value.
- llvm::APSInt Result;
- if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
- Result.isSigned() &&
- !((!StrictlyPositive && Result.isNonNegative()) ||
- (StrictlyPositive && Result.isStrictlyPositive()))) {
- SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
- << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
- << ValExpr->getSourceRange();
- return false;
+ if (Optional<llvm::APSInt> Result =
+ ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
+ if (Result->isSigned() &&
+ !((!StrictlyPositive && Result->isNonNegative()) ||
+ (StrictlyPositive && Result->isStrictlyPositive()))) {
+ SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
+ << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
+ << ValExpr->getSourceRange();
+ return false;
+ }
}
if (!BuildCapture)
return true;
@@ -12681,7 +12957,8 @@ ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
return E;
llvm::APSInt Result;
- ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
+ ExprResult ICE =
+ VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
if (ICE.isInvalid())
return ExprError();
if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
@@ -13263,9 +13540,9 @@ OMPClause *Sema::ActOnOpenMPScheduleClause(
// OpenMP [2.7.1, Restrictions]
// chunk_size must be a loop invariant integer expression with a positive
// value.
- llvm::APSInt Result;
- if (ValExpr->isIntegerConstantExpr(Result, Context)) {
- if (Result.isSigned() && !Result.isStrictlyPositive()) {
+ if (Optional<llvm::APSInt> Result =
+ ValExpr->getIntegerConstantExpr(Context)) {
+ if (Result->isSigned() && !Result->isStrictlyPositive()) {
Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
<< "schedule" << 1 << ChunkSize->getSourceRange();
return nullptr;
@@ -13522,7 +13799,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
- SourceLocation ExtraModifierLoc) {
+ SourceLocation ExtraModifierLoc,
+ ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
+ ArrayRef<SourceLocation> MotionModifiersLoc) {
SourceLocation StartLoc = Locs.StartLoc;
SourceLocation LParenLoc = Locs.LParenLoc;
SourceLocation EndLoc = Locs.EndLoc;
@@ -13599,12 +13878,14 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
break;
case OMPC_to:
- Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
- ReductionOrMapperId, Locs);
+ Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
+ ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
+ ColonLoc, VarList, Locs);
break;
case OMPC_from:
- Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
- ReductionOrMapperId, Locs);
+ Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
+ ReductionOrMapperIdScopeSpec,
+ ReductionOrMapperId, ColonLoc, VarList, Locs);
break;
case OMPC_use_device_ptr:
Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
@@ -14003,7 +14284,10 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
// from the worksharing construct.
if (isOpenMPTaskingDirective(CurrDir)) {
DVar = DSAStack->hasInnermostDSA(
- D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
+ D,
+ [](OpenMPClauseKind C, bool AppliedToPointee) {
+ return C == OMPC_reduction && !AppliedToPointee;
+ },
[](OpenMPDirectiveKind K) {
return isOpenMPParallelDirective(K) ||
isOpenMPWorksharingDirective(K) ||
@@ -14296,7 +14580,7 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(
if (!isOpenMPCapturedDecl(D))
ExprCaptures.push_back(Ref->getDecl());
}
- if (TopDVar.CKind == OMPC_firstprivate ||
+ if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
(!isOpenMPCapturedDecl(D) &&
Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
ExprResult RefRes = DefaultLvalueConversion(Ref);
@@ -14394,7 +14678,11 @@ public:
if (DVar.CKind != OMPC_unknown)
return true;
DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
- VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
+ VD,
+ [](OpenMPClauseKind C, bool AppliedToPointee) {
+ return isOpenMPPrivate(C) && !AppliedToPointee;
+ },
+ [](OpenMPDirectiveKind) { return true; },
/*FromParent=*/true);
return DVarPrivate.CKind != OMPC_unknown;
}
@@ -15027,6 +15315,17 @@ static bool actOnOMPReductionKindClause(
continue;
}
}
+ } else {
+ // Threadprivates cannot be shared between threads, so dignose if the base
+ // is a threadprivate variable.
+ DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
+ if (DVar.CKind == OMPC_threadprivate) {
+ S.Diag(ELoc, diag::err_omp_wrong_dsa)
+ << getOpenMPClauseName(DVar.CKind)
+ << getOpenMPClauseName(OMPC_reduction);
+ reportOriginalDsa(S, Stack, D, DVar);
+ continue;
+ }
}
// Try to find 'declare reduction' corresponding construct before using
@@ -15153,6 +15452,7 @@ static bool actOnOMPReductionKindClause(
auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
if (DRD->getInitializer()) {
+ S.ActOnUninitializedDecl(PrivateVD);
Init = DRDRef;
RHSVD->setInit(DRDRef);
RHSVD->setInitStyle(VarDecl::CallInit);
@@ -15259,10 +15559,19 @@ static bool actOnOMPReductionKindClause(
llvm_unreachable("Unexpected reduction operation");
}
}
- if (Init && DeclareReductionRef.isUnset())
+ if (Init && DeclareReductionRef.isUnset()) {
S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
- else if (!Init)
+ // Store initializer for single element in private copy. Will be used
+ // during codegen.
+ PrivateVD->setInit(RHSVD->getInit());
+ PrivateVD->setInitStyle(RHSVD->getInitStyle());
+ } else if (!Init) {
S.ActOnUninitializedDecl(RHSVD);
+ // Store initializer for single element in private copy. Will be used
+ // during codegen.
+ PrivateVD->setInit(RHSVD->getInit());
+ PrivateVD->setInitStyle(RHSVD->getInitStyle());
+ }
if (RHSVD->isInvalidDecl())
continue;
if (!RHSVD->hasInit() &&
@@ -15276,10 +15585,6 @@ static bool actOnOMPReductionKindClause(
<< D;
continue;
}
- // Store initializer for single element in private copy. Will be used during
- // codegen.
- PrivateVD->setInit(RHSVD->getInit());
- PrivateVD->setInitStyle(RHSVD->getInitStyle());
DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
ExprResult ReductionOp;
if (DeclareReductionRef.isUsable()) {
@@ -15290,12 +15595,12 @@ static bool actOnOMPReductionKindClause(
if (!BasePath.empty()) {
LHS = S.DefaultLvalueConversion(LHS.get());
RHS = S.DefaultLvalueConversion(RHS.get());
- LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
- CK_UncheckedDerivedToBase, LHS.get(),
- &BasePath, LHS.get()->getValueKind());
- RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
- CK_UncheckedDerivedToBase, RHS.get(),
- &BasePath, RHS.get()->getValueKind());
+ LHS = ImplicitCastExpr::Create(
+ Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
+ LHS.get()->getValueKind(), FPOptionsOverride());
+ RHS = ImplicitCastExpr::Create(
+ Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
+ RHS.get()->getValueKind(), FPOptionsOverride());
}
FunctionProtoType::ExtProtoInfo EPI;
QualType Params[] = {PtrRedTy, PtrRedTy};
@@ -15305,7 +15610,8 @@ static bool actOnOMPReductionKindClause(
S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
Expr *Args[] = {LHS.get(), RHS.get()};
ReductionOp =
- CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
+ CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
+ S.CurFPFeatureOverrides());
} else {
ReductionOp = S.BuildBinOp(
Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
@@ -15465,7 +15771,8 @@ static bool actOnOMPReductionKindClause(
// correct analysis of in_reduction clauses.
if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
Modifier = OMPC_REDUCTION_task;
- Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier);
+ Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
+ ASE || OASE);
if (Modifier == OMPC_REDUCTION_task &&
(CurrDir == OMPD_taskgroup ||
((isOpenMPParallelDirective(CurrDir) ||
@@ -15736,12 +16043,12 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
// Warn about zero linear step (it would be probably better specified as
// making corresponding variables 'const').
- llvm::APSInt Result;
- bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
- if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
- Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
- << (Vars.size() > 1);
- if (!IsConstant && CalcStep.isUsable()) {
+ if (Optional<llvm::APSInt> Result =
+ StepExpr->getIntegerConstantExpr(Context)) {
+ if (!Result->isNegative() && !Result->isStrictlyPositive())
+ Diag(StepLoc, diag::warn_omp_linear_step_zero)
+ << Vars[0] << (Vars.size() > 1);
+ } else if (CalcStep.isUsable()) {
// Calculate the step beforehand instead of doing this on each iteration.
// (This is not used if the number of iterations may be kfold-ed).
CalcStepExpr = CalcStep.get();
@@ -16645,11 +16952,14 @@ namespace {
class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
Sema &SemaRef;
OpenMPClauseKind CKind = OMPC_unknown;
+ OpenMPDirectiveKind DKind = OMPD_unknown;
OMPClauseMappableExprCommon::MappableExprComponentList &Components;
+ bool IsNonContiguous = false;
bool NoDiagnose = false;
const Expr *RelevantExpr = nullptr;
bool AllowUnitySizeArraySection = true;
bool AllowWholeSizeArraySection = true;
+ bool AllowAnotherPtr = true;
SourceLocation ELoc;
SourceRange ERange;
@@ -16674,7 +16984,7 @@ public:
assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
RelevantExpr = DRE;
// Record the component.
- Components.emplace_back(DRE, DRE->getDecl());
+ Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
return true;
}
@@ -16746,7 +17056,7 @@ public:
AllowWholeSizeArraySection = false;
// Record the component.
- Components.emplace_back(ME, FD);
+ Components.emplace_back(ME, FD, IsNonContiguous);
return RelevantExpr || Visit(E);
}
@@ -16784,7 +17094,7 @@ public:
}
// Record the component - we don't have any declaration associated.
- Components.emplace_back(AE, nullptr);
+ Components.emplace_back(AE, nullptr, IsNonContiguous);
return RelevantExpr || Visit(E);
}
@@ -16823,6 +17133,13 @@ public:
// pointer. Otherwise, only unitary sections are accepted.
if (NotWhole || IsPointer)
AllowWholeSizeArraySection = false;
+ } else if (DKind == OMPD_target_update &&
+ SemaRef.getLangOpts().OpenMP >= 50) {
+ if (IsPointer && !AllowAnotherPtr)
+ SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
+ << /*array of unknown bound */ 1;
+ else
+ IsNonContiguous = true;
} else if (AllowUnitySizeArraySection && NotUnity) {
// A unity or whole array section is not allowed and that is not
// compatible with the properties of the current array section.
@@ -16832,6 +17149,9 @@ public:
return false;
}
+ if (IsPointer)
+ AllowAnotherPtr = false;
+
if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
Expr::EvalResult ResultR;
Expr::EvalResult ResultL;
@@ -16857,14 +17177,14 @@ public:
}
// Record the component - we don't have any declaration associated.
- Components.emplace_back(OASE, nullptr);
+ Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
return RelevantExpr || Visit(E);
}
bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
Expr *Base = E->getBase();
// Record the component - we don't have any declaration associated.
- Components.emplace_back(E, nullptr);
+ Components.emplace_back(E, nullptr, IsNonContiguous);
return Visit(Base->IgnoreParenImpCasts());
}
@@ -16877,7 +17197,7 @@ public:
}
if (!RelevantExpr) {
// Record the component if haven't found base decl.
- Components.emplace_back(UO, nullptr);
+ Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
}
return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
}
@@ -16893,7 +17213,7 @@ public:
// know the other subtree is just an offset)
Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
- Components.emplace_back(BO, nullptr);
+ Components.emplace_back(BO, nullptr, false);
assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
"Either LHS or RHS have base decl inside");
@@ -16904,7 +17224,12 @@ public:
bool VisitCXXThisExpr(CXXThisExpr *CTE) {
assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
RelevantExpr = CTE;
- Components.emplace_back(CTE, nullptr);
+ Components.emplace_back(CTE, nullptr, IsNonContiguous);
+ return true;
+ }
+ bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
+ assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
+ Components.emplace_back(COCE, nullptr, IsNonContiguous);
return true;
}
bool VisitStmt(Stmt *) {
@@ -16915,10 +17240,10 @@ public:
return RelevantExpr;
}
explicit MapBaseChecker(
- Sema &SemaRef, OpenMPClauseKind CKind,
+ Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
OMPClauseMappableExprCommon::MappableExprComponentList &Components,
bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
- : SemaRef(SemaRef), CKind(CKind), Components(Components),
+ : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
};
} // namespace
@@ -16930,13 +17255,30 @@ public:
static const Expr *checkMapClauseExpressionBase(
Sema &SemaRef, Expr *E,
OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
- OpenMPClauseKind CKind, bool NoDiagnose) {
+ OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
SourceLocation ELoc = E->getExprLoc();
SourceRange ERange = E->getSourceRange();
- MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc,
+ MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
ERange);
- if (Checker.Visit(E->IgnoreParens()))
+ if (Checker.Visit(E->IgnoreParens())) {
+ // Check if the highest dimension array section has length specified
+ if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
+ (CKind == OMPC_to || CKind == OMPC_from)) {
+ auto CI = CurComponents.rbegin();
+ auto CE = CurComponents.rend();
+ for (; CI != CE; ++CI) {
+ const auto *OASE =
+ dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
+ if (!OASE)
+ continue;
+ if (OASE && OASE->getLength())
+ break;
+ SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
+ << ERange;
+ }
+ }
return Checker.getFoundBase();
+ }
return nullptr;
}
@@ -17347,6 +17689,7 @@ static void checkMappableExpressionList(
auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
MapperId.setName(DeclNames.getIdentifier(
&SemaRef.getASTContext().Idents.get("default")));
+ MapperId.setLoc(StartLoc);
}
// Iterators to find the current unresolved mapper expression.
@@ -17413,7 +17756,8 @@ static void checkMappableExpressionList(
// Obtain the array or member expression bases if required. Also, fill the
// components array with all the components identified in the process.
const Expr *BE = checkMapClauseExpressionBase(
- SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
+ SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
+ /*NoDiagnose=*/false);
if (!BE)
continue;
@@ -17478,6 +17822,7 @@ static void checkMappableExpressionList(
/*CurrentRegionOnly=*/true, CurComponents, CKind))
break;
if (CKind == OMPC_map &&
+ (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
/*CurrentRegionOnly=*/false, CurComponents, CKind))
break;
@@ -17623,9 +17968,9 @@ OMPClause *Sema::ActOnOpenMPMapClause(
OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
- OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown,
- OMPC_MAP_MODIFIER_unknown,
- OMPC_MAP_MODIFIER_unknown};
+ OpenMPMapModifierKind Modifiers[] = {
+ OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
+ OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
// Process map-type-modifiers, flag errors for duplicate modifiers.
@@ -17944,10 +18289,10 @@ QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
return MapperType;
}
-OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
+Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
- Decl *PrevDeclInScope) {
+ Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
forRedeclarationInCurContext());
// [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
@@ -18007,48 +18352,51 @@ OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
Invalid = true;
}
auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
- MapperType, VN, PrevDMD);
- DC->addDecl(DMD);
+ MapperType, VN, Clauses, PrevDMD);
+ if (S)
+ PushOnScopeChains(DMD, S);
+ else
+ DC->addDecl(DMD);
DMD->setAccess(AS);
if (Invalid)
DMD->setInvalidDecl();
- // Enter new function scope.
- PushFunctionScope();
- setFunctionHasBranchProtectedScope();
-
- CurContext = DMD;
+ auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
+ VD->setDeclContext(DMD);
+ VD->setLexicalDeclContext(DMD);
+ DMD->addDecl(VD);
+ DMD->setMapperVarRef(MapperVarRef);
- return DMD;
+ return DeclGroupPtrTy::make(DeclGroupRef(DMD));
}
-void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
- Scope *S,
- QualType MapperType,
- SourceLocation StartLoc,
- DeclarationName VN) {
- VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
+ExprResult
+Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
+ SourceLocation StartLoc,
+ DeclarationName VN) {
+ TypeSourceInfo *TInfo =
+ Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
+ auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
+ StartLoc, StartLoc, VN.getAsIdentifierInfo(),
+ MapperType, TInfo, SC_None);
if (S)
- PushOnScopeChains(VD, S);
- else
- DMD->addDecl(VD);
- Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
- DMD->setMapperVarRef(MapperVarRefExpr);
+ PushOnScopeChains(VD, S, /*AddToContext=*/false);
+ Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
+ DSAStack->addDeclareMapperVarRef(E);
+ return E;
}
-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);
- }
+bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
+ assert(LangOpts.OpenMP && "Expected OpenMP mode.");
+ const Expr *Ref = DSAStack->getDeclareMapperVarRef();
+ if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
+ return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
+ return true;
+}
- return DeclGroupPtrTy::make(DeclGroupRef(D));
+const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
+ assert(LangOpts.OpenMP && "Expected OpenMP mode.");
+ return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
}
OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
@@ -18273,9 +18621,9 @@ OMPClause *Sema::ActOnOpenMPDistScheduleClause(
// OpenMP [2.7.1, Restrictions]
// chunk_size must be a loop invariant integer expression with a positive
// value.
- llvm::APSInt Result;
- if (ValExpr->isIntegerConstantExpr(Result, Context)) {
- if (Result.isSigned() && !Result.isStrictlyPositive()) {
+ if (Optional<llvm::APSInt> Result =
+ ValExpr->getIntegerConstantExpr(Context)) {
+ if (Result->isSigned() && !Result->isStrictlyPositive()) {
Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
<< "dist_schedule" << ChunkSize->getSourceRange();
return nullptr;
@@ -18326,20 +18674,38 @@ OMPClause *Sema::ActOnOpenMPDefaultmapClause(
bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
(LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
if (!isDefaultmapKind || !isDefaultmapModifier) {
- std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
+ StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
+ if (LangOpts.OpenMP == 50) {
+ StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
"'firstprivate', 'none', 'default'";
- std::string KindValue = "'scalar', 'aggregate', 'pointer'";
- if (!isDefaultmapKind && isDefaultmapModifier) {
- Diag(KindLoc, diag::err_omp_unexpected_clause_value)
- << KindValue << getOpenMPClauseName(OMPC_defaultmap);
- } else if (isDefaultmapKind && !isDefaultmapModifier) {
- Diag(MLoc, diag::err_omp_unexpected_clause_value)
- << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
+ if (!isDefaultmapKind && isDefaultmapModifier) {
+ Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+ << KindValue << getOpenMPClauseName(OMPC_defaultmap);
+ } else if (isDefaultmapKind && !isDefaultmapModifier) {
+ Diag(MLoc, diag::err_omp_unexpected_clause_value)
+ << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
+ } else {
+ Diag(MLoc, diag::err_omp_unexpected_clause_value)
+ << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
+ Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+ << KindValue << getOpenMPClauseName(OMPC_defaultmap);
+ }
} else {
- Diag(MLoc, diag::err_omp_unexpected_clause_value)
- << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
- Diag(KindLoc, diag::err_omp_unexpected_clause_value)
- << KindValue << getOpenMPClauseName(OMPC_defaultmap);
+ StringRef ModifierValue =
+ "'alloc', 'from', 'to', 'tofrom', "
+ "'firstprivate', 'none', 'default', 'present'";
+ if (!isDefaultmapKind && isDefaultmapModifier) {
+ Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+ << KindValue << getOpenMPClauseName(OMPC_defaultmap);
+ } else if (isDefaultmapKind && !isDefaultmapModifier) {
+ Diag(MLoc, diag::err_omp_unexpected_clause_value)
+ << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
+ } else {
+ Diag(MLoc, diag::err_omp_unexpected_clause_value)
+ << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
+ Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+ << KindValue << getOpenMPClauseName(OMPC_defaultmap);
+ }
}
return nullptr;
}
@@ -18377,14 +18743,14 @@ bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
Diag(Loc, diag::err_omp_region_not_file_context);
return false;
}
- ++DeclareTargetNestingLevel;
+ DeclareTargetNesting.push_back(Loc);
return true;
}
void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
- assert(DeclareTargetNestingLevel > 0 &&
+ assert(!DeclareTargetNesting.empty() &&
"Unexpected ActOnFinishOpenMPDeclareTargetDirective");
- --DeclareTargetNestingLevel;
+ DeclareTargetNesting.pop_back();
}
NamedDecl *
@@ -18437,19 +18803,25 @@ void Sema::ActOnOpenMPDeclareTargetName(
(ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
Diag(Loc, diag::warn_omp_declare_target_after_first_use);
+ auto *VD = cast<ValueDecl>(ND);
Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
- OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND));
- if (DevTy.hasValue() && *DevTy != DT) {
+ OMPDeclareTargetDeclAttr::getDeviceType(VD);
+ Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD);
+ if (DevTy.hasValue() && *DevTy != DT &&
+ (DeclareTargetNesting.empty() ||
+ *AttrLoc != DeclareTargetNesting.back())) {
Diag(Loc, diag::err_omp_device_type_mismatch)
<< OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
<< OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
return;
}
Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
- OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND));
- if (!Res) {
- auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT,
- SourceRange(Loc, Loc));
+ OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
+ if (!Res || (!DeclareTargetNesting.empty() &&
+ *AttrLoc == DeclareTargetNesting.back())) {
+ auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
+ Context, MT, DT, DeclareTargetNesting.size() + 1,
+ SourceRange(Loc, Loc));
ND->addAttr(A);
if (ASTMutationListener *ML = Context.getASTMutationListener())
ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
@@ -18541,7 +18913,9 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
isa<FunctionTemplateDecl>(D)) {
auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
Context, OMPDeclareTargetDeclAttr::MT_To,
- OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc));
+ OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(),
+ SourceRange(DeclareTargetNesting.back(),
+ DeclareTargetNesting.back()));
D->addAttr(A);
if (ASTMutationListener *ML = Context.getASTMutationListener())
ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
@@ -18554,11 +18928,31 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
}
-OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
- CXXScopeSpec &MapperIdScopeSpec,
- DeclarationNameInfo &MapperId,
- const OMPVarListLocTy &Locs,
- ArrayRef<Expr *> UnresolvedMappers) {
+OMPClause *Sema::ActOnOpenMPToClause(
+ ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
+ ArrayRef<SourceLocation> MotionModifiersLoc,
+ CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
+ SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
+ const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
+ OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
+ OMPC_MOTION_MODIFIER_unknown};
+ SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
+
+ // Process motion-modifiers, flag errors for duplicate modifiers.
+ unsigned Count = 0;
+ for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
+ if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
+ llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
+ Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
+ continue;
+ }
+ assert(Count < NumberOfOMPMotionModifiers &&
+ "Modifiers exceed the allowed number of motion modifiers");
+ Modifiers[Count] = MotionModifiers[I];
+ ModifiersLoc[Count] = MotionModifiersLoc[I];
+ ++Count;
+ }
+
MappableVarListInfo MVLI(VarList);
checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
MapperIdScopeSpec, MapperId, UnresolvedMappers);
@@ -18567,15 +18961,35 @@ OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
return OMPToClause::Create(
Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
- MVLI.VarComponents, MVLI.UDMapperList,
+ MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
}
-OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
- CXXScopeSpec &MapperIdScopeSpec,
- DeclarationNameInfo &MapperId,
- const OMPVarListLocTy &Locs,
- ArrayRef<Expr *> UnresolvedMappers) {
+OMPClause *Sema::ActOnOpenMPFromClause(
+ ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
+ ArrayRef<SourceLocation> MotionModifiersLoc,
+ CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
+ SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
+ const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
+ OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
+ OMPC_MOTION_MODIFIER_unknown};
+ SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
+
+ // Process motion-modifiers, flag errors for duplicate modifiers.
+ unsigned Count = 0;
+ for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
+ if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
+ llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
+ Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
+ continue;
+ }
+ assert(Count < NumberOfOMPMotionModifiers &&
+ "Modifiers exceed the allowed number of motion modifiers");
+ Modifiers[Count] = MotionModifiers[I];
+ ModifiersLoc[Count] = MotionModifiersLoc[I];
+ ++Count;
+ }
+
MappableVarListInfo MVLI(VarList);
checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
MapperIdScopeSpec, MapperId, UnresolvedMappers);
@@ -18584,7 +18998,7 @@ OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
return OMPFromClause::Create(
Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
- MVLI.VarComponents, MVLI.UDMapperList,
+ MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
}
@@ -18661,8 +19075,8 @@ OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
// only need a component.
MVLI.VarBaseDeclarations.push_back(D);
MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
- MVLI.VarComponents.back().push_back(
- OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
+ MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
+ /*IsNonContiguous=*/false);
}
if (MVLI.ProcessedVarList.empty())
@@ -18713,8 +19127,8 @@ OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
- MVLI.VarComponents.back().push_back(
- OMPClauseMappableExprCommon::MappableComponent(Component, D));
+ MVLI.VarComponents.back().emplace_back(Component, D,
+ /*IsNonContiguous=*/false);
}
if (MVLI.ProcessedVarList.empty())
@@ -18780,7 +19194,8 @@ OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
// Store the components in the stack so that they can be used to check
// against other clauses later on.
- OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
+ OMPClauseMappableExprCommon::MappableComponent MC(
+ SimpleRefExpr, D, /*IsNonContiguous=*/false);
DSAStack->addMappableExpressionComponents(
D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
@@ -19022,7 +19437,7 @@ OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
[](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
!findOMPAlloctraitT(*this, StartLoc, DSAStack))
return nullptr;
- llvm::SmallSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
+ llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
StringRef Allocator =