/// Vector of previously declared requires directives
SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
+ /// omp_allocator_handle_t type.
+ QualType OMPAllocatorHandleT;
+ /// Expression for the predefined allocators.
+ Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
+ nullptr};
public:
explicit DSAStackTy(Sema &S) : SemaRef(S) {}
+ /// Sets omp_allocator_handle_t type.
+ void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
+ /// Gets omp_allocator_handle_t type.
+ QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
+ /// Sets the given default allocator.
+ void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
+ Expr *Allocator) {
+ OMPPredefinedAllocators[AllocatorKind] = Allocator;
+ }
+ /// Returns the specified default allocator.
+ Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
+ return OMPPredefinedAllocators[AllocatorKind];
+ }
+
bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
OpenMPClauseKind getClauseParsingMode() const {
assert(isClauseParsingMode() && "Must be in clause parsing mode.");
return D;
}
+static OMPAllocateDeclAttr::AllocatorTypeTy
+getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
+ if (!Allocator)
+ return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
+ if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
+ Allocator->isInstantiationDependent() ||
+ Allocator->containsUnexpandedParameterPack() ||
+ !Allocator->isEvaluatable(S.getASTContext()))
+ return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
+ bool Suppress = S.getDiagnostics().getSuppressAllDiagnostics();
+ S.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
+ auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
+ for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
+ I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
+ auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
+ Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
+ // Compare allocator with the predefined allocator and if true - return
+ // predefined allocator kind.
+ ExprResult DefAllocRes = S.DefaultLvalueConversion(DefAllocator);
+ ExprResult AllocRes = S.DefaultLvalueConversion(Allocator);
+ ExprResult CompareRes = S.CreateBuiltinBinOp(
+ Allocator->getExprLoc(), BO_EQ, DefAllocRes.get(), AllocRes.get());
+ if (!CompareRes.isUsable())
+ continue;
+ bool Result;
+ if (!CompareRes.get()->EvaluateAsBooleanCondition(Result,
+ S.getASTContext()))
+ continue;
+ if (Result) {
+ AllocatorKindRes = AllocatorKind;
+ break;
+ }
+
+ }
+ S.getDiagnostics().setSuppressAllDiagnostics(Suppress);
+ return AllocatorKindRes;
+}
+
Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
SourceLocation Loc, ArrayRef<Expr *> VarList,
ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
Expr *Allocator = nullptr;
if (!Clauses.empty())
Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
+ OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
+ getAllocatorKind(*this, DSAStack, Allocator);
SmallVector<Expr *, 8> Vars;
for (Expr *RefExpr : VarList) {
auto *DE = cast<DeclRefExpr>(RefExpr);
// must be used.
if (VD->hasAttr<OMPAllocateDeclAttr>()) {
const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
- const Expr *PrevAllocator = A->getAllocator();
- bool AllocatorsMatch = false;
- if (Allocator && PrevAllocator) {
+ Expr *PrevAllocator = A->getAllocator();
+ OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
+ getAllocatorKind(*this, DSAStack, PrevAllocator);
+ bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
+ if (AllocatorsMatch && Allocator && PrevAllocator) {
const Expr *AE = Allocator->IgnoreParenImpCasts();
const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
llvm::FoldingSetNodeID AEId, PAEId;
AE->Profile(AEId, Context, /*Canonical=*/true);
PAE->Profile(PAEId, Context, /*Canonical=*/true);
AllocatorsMatch = AEId == PAEId;
- } else if (!Allocator && !PrevAllocator) {
- AllocatorsMatch = true;
- } else {
- const Expr *AE = Allocator ? Allocator : PrevAllocator;
- // In this case the specified allocator must be the default one.
- AE = AE->IgnoreParenImpCasts();
- if (const auto *DRE = dyn_cast<DeclRefExpr>(AE)) {
- DeclarationName DN = DRE->getDecl()->getDeclName();
- AllocatorsMatch =
- DN.isIdentifier() &&
- DN.getAsIdentifierInfo()->isStr("omp_default_mem_alloc");
- }
}
if (!AllocatorsMatch) {
SmallString<256> AllocatorBuffer;
!Allocator->isInstantiationDependent() &&
!Allocator->containsUnexpandedParameterPack())) &&
!VD->hasAttr<OMPAllocateDeclAttr>()) {
- Attr *A = OMPAllocateDeclAttr::CreateImplicit(Context, Allocator,
- DE->getSourceRange());
+ Attr *A = OMPAllocateDeclAttr::CreateImplicit(
+ Context, AllocatorKind, Allocator, DE->getSourceRange());
VD->addAttr(A);
if (ASTMutationListener *ML = Context.getASTMutationListener())
ML->DeclarationMarkedOpenMPAllocate(VD, A);
}
/// Tries to find omp_allocator_handle_t type.
-static bool FindOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
- QualType &OMPAllocatorHandleT) {
+static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
+ DSAStackTy *Stack) {
+ QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
if (!OMPAllocatorHandleT.isNull())
return true;
- DeclarationName OMPAllocatorHandleTName =
- &S.getASTContext().Idents.get("omp_allocator_handle_t");
- auto *TD = dyn_cast_or_null<TypeDecl>(S.LookupSingleName(
- S.TUScope, OMPAllocatorHandleTName, Loc, Sema::LookupAnyName));
- if (!TD) {
+ // Build the predefined allocator expressions.
+ bool ErrorFound = false;
+ for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
+ I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
+ auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
+ StringRef Allocator =
+ OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
+ DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
+ auto *VD = dyn_cast_or_null<ValueDecl>(
+ S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
+ if (!VD) {
+ ErrorFound = true;
+ break;
+ }
+ QualType AllocatorType =
+ VD->getType().getNonLValueExprType(S.getASTContext());
+ ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
+ if (!Res.isUsable()) {
+ ErrorFound = true;
+ break;
+ }
+ if (OMPAllocatorHandleT.isNull())
+ OMPAllocatorHandleT = AllocatorType;
+ if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
+ ErrorFound = true;
+ break;
+ }
+ Stack->setAllocator(AllocatorKind, Res.get());
+ }
+ if (ErrorFound) {
S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
return false;
}
- OMPAllocatorHandleT = S.getASTContext().getTypeDeclType(TD);
+ OMPAllocatorHandleT.addConst();
+ Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
return true;
}
SourceLocation EndLoc) {
// OpenMP [2.11.3, allocate Directive, Description]
// allocator is an expression of omp_allocator_handle_t type.
- if (!FindOMPAllocatorHandleT(*this, A->getExprLoc(), OMPAllocatorHandleT))
+ if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
return nullptr;
ExprResult Allocator = DefaultLvalueConversion(A);
if (Allocator.isInvalid())
return nullptr;
- Allocator = PerformImplicitConversion(Allocator.get(), OMPAllocatorHandleT,
+ Allocator = PerformImplicitConversion(Allocator.get(),
+ DSAStack->getOMPAllocatorHandleT(),
Sema::AA_Initializing,
/*AllowExplicit=*/true);
if (Allocator.isInvalid())