diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/DeclOpenMP.cpp | 21 | ||||
-rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 5 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprMember.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 94 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTCommon.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 6 |
12 files changed, 144 insertions, 29 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 72587e388e4..b699bec083c 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -655,6 +655,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCCategoryImpl: case Import: case OMPThreadPrivate: + case OMPCapturedField: case Empty: // Never looked up by name. return 0; diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp index 493e2cd4122..33677bacea7 100644 --- a/clang/lib/AST/DeclOpenMP.cpp +++ b/clang/lib/AST/DeclOpenMP.cpp @@ -7,7 +7,8 @@ // //===----------------------------------------------------------------------===// /// \file -/// \brief This file implements OMPThreadPrivateDecl class. +/// \brief This file implements OMPThreadPrivateDecl, OMPCapturedFieldDecl +/// classes. /// //===----------------------------------------------------------------------===// @@ -52,3 +53,21 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) { std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>()); } +//===----------------------------------------------------------------------===// +// OMPCapturedFieldDecl Implementation. +//===----------------------------------------------------------------------===// + +void OMPCapturedFieldDecl::anchor() {} + +OMPCapturedFieldDecl *OMPCapturedFieldDecl::Create(ASTContext &C, + DeclContext *DC, + IdentifierInfo *Id, + QualType T) { + return new (C, DC) OMPCapturedFieldDecl(C, DC, Id, T); +} + +OMPCapturedFieldDecl *OMPCapturedFieldDecl::CreateDeserialized(ASTContext &C, + unsigned ID) { + return new (C, ID) OMPCapturedFieldDecl(C, nullptr, nullptr, QualType()); +} + diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 19c7da3074b..1a0e1488bb1 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -92,6 +92,7 @@ namespace { void VisitUsingDecl(UsingDecl *D); void VisitUsingShadowDecl(UsingShadowDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + void VisitOMPCapturedFieldDecl(OMPCapturedFieldDecl *D); void PrintTemplateParameters(const TemplateParameterList *Params, const TemplateArgumentList *Args = nullptr); @@ -1366,3 +1367,7 @@ void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { } } +void DeclPrinter::VisitOMPCapturedFieldDecl(OMPCapturedFieldDecl *D) { + D->getInit()->printPretty(Out, nullptr, Policy, Indentation); +} + diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index d9c3457f486..830eeb9efac 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -16,6 +16,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -763,15 +764,16 @@ template<typename T> void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) { for (typename T::varlist_iterator I = Node->varlist_begin(), E = Node->varlist_end(); - I != E; ++I) { + I != E; ++I) { assert(*I && "Expected non-null Stmt"); + OS << (I == Node->varlist_begin() ? StartSym : ','); if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*I)) { - OS << (I == Node->varlist_begin() ? StartSym : ','); - cast<NamedDecl>(DRE->getDecl())->printQualifiedName(OS); - } else { - OS << (I == Node->varlist_begin() ? StartSym : ','); + if (auto *CFD = dyn_cast<OMPCapturedFieldDecl>(DRE->getDecl())) + CFD->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy, 0); + else + DRE->getDecl()->printQualifiedName(OS); + } else (*I)->printPretty(OS, nullptr, Policy, 0); - } } } diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index e8a4d552923..e18e86da029 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -92,6 +92,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::Label: // __label__ x; case Decl::Import: case Decl::OMPThreadPrivate: + case Decl::OMPCapturedField: case Decl::Empty: // None of these decls require codegen support. return; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 20a0e3f6a71..0c17aa1911c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2874,6 +2874,7 @@ ExprResult Sema::BuildDeclarationNameExpr( case Decl::Var: case Decl::VarTemplateSpecialization: case Decl::VarTemplatePartialSpecialization: + case Decl::OMPCapturedField: // In C, "extern void blah;" is valid and is an r-value. if (!getLangOpts().CPlusPlus && !type.hasQualifiers() && diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index f62b5a58e84..415587498d4 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -1735,9 +1735,19 @@ BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow, FoundDecl, Field); if (Base.isInvalid()) return ExprError(); - return BuildMemberExpr(S, S.Context, Base.get(), IsArrow, OpLoc, SS, - /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl, - MemberNameInfo, MemberType, VK, OK); + MemberExpr *ME = + BuildMemberExpr(S, S.Context, Base.get(), IsArrow, OpLoc, SS, + /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl, + MemberNameInfo, MemberType, VK, OK); + + // Build a reference to a private copy for non-static data members in + // non-static member functions, privatized by OpenMP constructs. + if (S.getLangOpts().OpenMP && IsArrow && + isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) { + if (auto *PrivateCopy = S.IsOpenMPCapturedDecl(Field)) + return S.getOpenMPCapturedExpr(PrivateCopy, VK, OK); + } + return ME; } /// Builds an implicit member access expression. The current context diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 5b38f436fb7..d4c1f98c998 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -71,10 +71,11 @@ public: OpenMPDirectiveKind DKind; OpenMPClauseKind CKind; Expr *RefExpr; + DeclRefExpr *PrivateCopy; SourceLocation ImplicitDSALoc; DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr), - ImplicitDSALoc() {} + PrivateCopy(nullptr), ImplicitDSALoc() {} }; private: @@ -83,11 +84,12 @@ private: struct DSAInfo { OpenMPClauseKind Attributes; Expr *RefExpr; + DeclRefExpr *PrivateCopy; }; - typedef llvm::SmallDenseMap<ValueDecl *, DSAInfo, 64> DeclSAMapTy; - typedef llvm::SmallDenseMap<ValueDecl *, Expr *, 64> AlignedMapTy; + typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy; + typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy; typedef llvm::DenseMap<ValueDecl *, unsigned> LoopControlVariablesMapTy; - typedef llvm::SmallDenseMap<ValueDecl *, MapInfo, 64> MappedDeclsTy; + typedef llvm::DenseMap<ValueDecl *, MapInfo> MappedDeclsTy; typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> CriticalsWithHintsTy; @@ -195,7 +197,8 @@ public: ValueDecl *getParentLoopControlVariable(unsigned I); /// \brief Adds explicit data sharing attribute to the specified declaration. - void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A); + void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, + DeclRefExpr *PrivateCopy = nullptr); /// \brief Returns data sharing attributes from top of the stack for the /// specified declaration. @@ -434,6 +437,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter, // attributes. if (Iter->SharingMap.count(D)) { DVar.RefExpr = Iter->SharingMap[D].RefExpr; + DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; DVar.CKind = Iter->SharingMap[D].Attributes; DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; return DVar; @@ -547,15 +551,20 @@ ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { return nullptr; } -void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A) { +void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, + DeclRefExpr *PrivateCopy) { D = getCanonicalDecl(D); if (A == OMPC_threadprivate) { Stack[0].SharingMap[D].Attributes = A; Stack[0].SharingMap[D].RefExpr = E; + Stack[0].SharingMap[D].PrivateCopy = nullptr; } else { assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); Stack.back().SharingMap[D].Attributes = A; Stack.back().SharingMap[D].RefExpr = E; + Stack.back().SharingMap[D].PrivateCopy = PrivateCopy; + if (PrivateCopy) + addDSA(PrivateCopy->getDecl(), PrivateCopy, A); } } @@ -682,6 +691,7 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { auto I = std::prev(StartI); if (I->SharingMap.count(D)) { DVar.RefExpr = I->SharingMap[D].RefExpr; + DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; DVar.CKind = I->SharingMap[D].Attributes; DVar.ImplicitDSALoc = I->DefaultAttrLoc; } @@ -886,7 +896,7 @@ bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, return IsByRef; } -bool Sema::IsOpenMPCapturedDecl(ValueDecl *D) { +VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { assert(LangOpts.OpenMP && "OpenMP is not allowed"); D = getCanonicalDecl(D); @@ -900,18 +910,16 @@ bool Sema::IsOpenMPCapturedDecl(ValueDecl *D) { auto *VD = dyn_cast<VarDecl>(D); if (VD && !VD->hasLocalStorage()) { if (DSAStack->getCurrentDirective() == OMPD_target && - !DSAStack->isClauseParsingMode()) { - return true; - } + !DSAStack->isClauseParsingMode()) + return VD; if (DSAStack->getCurScope() && DSAStack->hasDirective( [](OpenMPDirectiveKind K, const DeclarationNameInfo &DNI, SourceLocation Loc) -> bool { return isOpenMPTargetExecutionDirective(K); }, - false)) { - return true; - } + false)) + return VD; } if (DSAStack->getCurrentDirective() != OMPD_unknown && @@ -921,15 +929,16 @@ bool Sema::IsOpenMPCapturedDecl(ValueDecl *D) { (VD && VD->hasLocalStorage() && isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || (VD && DSAStack->isForceVarCapturing())) - return true; + return VD; auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) - return true; + return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, MatchesAlways(), DSAStack->isClauseParsingMode()); - return DVarPrivate.CKind != OMPC_unknown; + if (DVarPrivate.CKind != OMPC_unknown) + return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); } - return false; + return nullptr; } bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { @@ -6958,6 +6967,50 @@ OMPClause *Sema::ActOnOpenMPVarListClause( return Res; } +static DeclRefExpr *buildCapture(Sema &S, IdentifierInfo *Id, + Expr *CaptureExpr) { + ASTContext &C = S.getASTContext(); + Expr *Init = CaptureExpr->IgnoreImpCasts(); + QualType Ty = Init->getType(); + if (CaptureExpr->getObjectKind() == OK_Ordinary) { + if (S.getLangOpts().CPlusPlus) + Ty = C.getLValueReferenceType(Ty); + else { + Ty = C.getPointerType(Ty); + ExprResult Res = + S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); + if (!Res.isUsable()) + return nullptr; + Init = Res.get(); + } + } + auto *CFD = OMPCapturedFieldDecl::Create(C, S.CurContext, Id, Ty); + S.CurContext->addHiddenDecl(CFD); + S.AddInitializerToDecl(CFD, Init, /*DirectInit=*/false, + /*TypeMayContainAuto=*/true); + return buildDeclRefExpr(S, CFD, Ty.getNonReferenceType(), SourceLocation()); +} + +ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, + ExprObjectKind OK) { + SourceLocation Loc = Capture->getInit()->getExprLoc(); + ExprResult Res = BuildDeclRefExpr( + Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); + if (!Res.isUsable()) + return ExprError(); + if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { + Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); + if (!Res.isUsable()) + return ExprError(); + } + if (VK != VK_LValue && Res.get()->isGLValue()) { + Res = DefaultLvalueConversion(Res.get()); + if (!Res.isUsable()) + return ExprError(); + } + return Res; +} + OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -7050,8 +7103,11 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, auto VDPrivateRefExpr = buildDeclRefExpr( *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); - DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private); - Vars.push_back(RefExpr->IgnoreParens()); + DeclRefExpr *Ref = nullptr; + if (!VD) + Ref = buildCapture(*this, D->getIdentifier(), RefExpr); + DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); + Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); PrivateCopies.push_back(VDPrivateRefExpr); } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 625760c68ca..0f011ab159a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2483,6 +2483,11 @@ Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl( return TD; } +Decl *TemplateDeclInstantiator::VisitOMPCapturedFieldDecl( + OMPCapturedFieldDecl * /*D*/) { + llvm_unreachable("Should not be met in templates"); +} + Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { return VisitFunctionDecl(D, nullptr); } diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 2b78d745864..68621f3709f 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -329,6 +329,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::ClassScopeFunctionSpecialization: case Decl::Import: case Decl::OMPThreadPrivate: + case Decl::OMPCapturedField: case Decl::BuiltinTemplate: return false; diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index b249da99462..074de1a71ac 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -350,6 +350,7 @@ namespace clang { void VisitObjCPropertyDecl(ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + void VisitOMPCapturedFieldDecl(OMPCapturedFieldDecl *D); /// We've merged the definition \p MergedDef into the existing definition /// \p Def. Ensure that \p Def is made visible whenever \p MergedDef is made @@ -2360,6 +2361,10 @@ void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { D->setVars(Vars); } +void ASTDeclReader::VisitOMPCapturedFieldDecl(OMPCapturedFieldDecl *D) { + VisitVarDecl(D); +} + //===----------------------------------------------------------------------===// // Attribute Reading //===----------------------------------------------------------------------===// @@ -3323,6 +3328,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_OMP_THREADPRIVATE: D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record[Idx++]); break; + case DECL_OMP_CAPTUREDFIELD: + D = OMPCapturedFieldDecl::CreateDeserialized(Context, ID); + break; case DECL_EMPTY: D = EmptyDecl::CreateDeserialized(Context, ID); break; diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 54bba282ab8..4620f56055b 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -131,6 +131,7 @@ namespace clang { void VisitObjCPropertyDecl(ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + void VisitOMPCapturedFieldDecl(OMPCapturedFieldDecl *D); /// Add an Objective-C type parameter list to the given record. void AddObjCTypeParamList(ObjCTypeParamList *typeParams) { @@ -1628,6 +1629,11 @@ void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { Code = serialization::DECL_OMP_THREADPRIVATE; } +void ASTDeclWriter::VisitOMPCapturedFieldDecl(OMPCapturedFieldDecl *D) { + VisitVarDecl(D); + Code = serialization::DECL_OMP_CAPTUREDFIELD; +} + //===----------------------------------------------------------------------===// // ASTWriter Implementation //===----------------------------------------------------------------------===// |