Thanks. It didn't pass with i686-mingw32. // LAMBDA: call // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
call x86_thiscallcc void @_ZN2SSC1ERi(%struct.SS* %ss, i32* dereferenceable(4) @_ZZ4mainE5sivar) call x86_thiscallcc void @"_ZZ4mainENK3$_0clEv"(%class.anon* %temp.lvalue) The latter LAMBDA hit "callcc void @_ZN2SSC1ERi(" Fixed in r260093. I suggest like; // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](%class.anon* On Mon, Feb 8, 2016 at 10:02 PM Alexey Bataev <a.bat...@hotmail.com> wrote: > Yes, I know, will be fixed in few minutes > > Best regards, > Alexey Bataev > ============= > Software Engineer > Intel Compiler Team > > 08.02.2016 15:43, NAKAMURA Takumi пишет: > > The test is incompatible to i686-pc-win32. See also > http://bb.pgr.jp/builders/ninja-clang-i686-msc18-R/builds/5498 > > On Mon, Feb 8, 2016 at 6:33 PM Alexey Bataev via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> Author: abataev >> Date: Mon Feb 8 03:29:13 2016 >> New Revision: 260077 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=260077&view=rev >> Log: >> [OPENMP 4.5] Ccapture/codegen of private non-static data members. >> OpenMP 4.5 introduces privatization of non-static data members of current >> class in non-static member functions. >> To correctly handle such kind of privatization a new (pseudo)declaration >> VarDecl-based node is added. It allows to reuse an existing code for >> capturing variables in Lambdas/Block/Captured blocks of code for correct >> privatization and codegen. >> >> Modified: >> cfe/trunk/include/clang/AST/DeclOpenMP.h >> cfe/trunk/include/clang/AST/RecursiveASTVisitor.h >> cfe/trunk/include/clang/Basic/DeclNodes.td >> cfe/trunk/include/clang/Sema/Sema.h >> cfe/trunk/include/clang/Serialization/ASTBitCodes.h >> cfe/trunk/lib/AST/DeclBase.cpp >> cfe/trunk/lib/AST/DeclOpenMP.cpp >> cfe/trunk/lib/AST/DeclPrinter.cpp >> cfe/trunk/lib/AST/StmtPrinter.cpp >> cfe/trunk/lib/CodeGen/CGDecl.cpp >> cfe/trunk/lib/Sema/SemaExpr.cpp >> cfe/trunk/lib/Sema/SemaExprMember.cpp >> cfe/trunk/lib/Sema/SemaOpenMP.cpp >> cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp >> cfe/trunk/lib/Serialization/ASTCommon.cpp >> cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >> cfe/trunk/lib/Serialization/ASTWriterDecl.cpp >> cfe/trunk/test/OpenMP/parallel_private_codegen.cpp >> cfe/trunk/tools/libclang/CIndex.cpp >> >> Modified: cfe/trunk/include/clang/AST/DeclOpenMP.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclOpenMP.h?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/include/clang/AST/DeclOpenMP.h (original) >> +++ cfe/trunk/include/clang/AST/DeclOpenMP.h Mon Feb 8 03:29:13 2016 >> @@ -87,6 +87,35 @@ public: >> static bool classofKind(Kind K) { return K == OMPThreadPrivate; } >> }; >> >> -} // end namespace clang >> +/// Pseudo declaration for capturing of non-static data members in >> non-static >> +/// member functions. >> +/// >> +/// Clang supports capturing of variables only, but OpenMP 4.5 allows to >> +/// privatize non-static members of current class in non-static member >> +/// functions. This pseudo-declaration allows properly handle this kind >> of >> +/// capture by wrapping captured expression into a variable-like >> declaration. >> +class OMPCapturedFieldDecl final : public VarDecl { >> + friend class ASTDeclReader; >> + void anchor() override; >> + >> + OMPCapturedFieldDecl(ASTContext &C, DeclContext *DC, IdentifierInfo >> *Id, >> + QualType Type) >> + : VarDecl(OMPCapturedField, C, DC, SourceLocation(), >> SourceLocation(), Id, >> + Type, nullptr, SC_None) { >> + setImplicit(); >> + } >> + >> +public: >> + static OMPCapturedFieldDecl *Create(ASTContext &C, DeclContext *DC, >> + IdentifierInfo *Id, QualType T); >> + >> + static OMPCapturedFieldDecl *CreateDeserialized(ASTContext &C, >> unsigned ID); >> + >> + // Implement isa/cast/dyncast/etc. >> + static bool classof(const Decl *D) { return classofKind(D->getKind()); >> } >> + static bool classofKind(Kind K) { return K == OMPCapturedField; } >> +}; >> + >> +} // end namespace clang >> >> #endif >> >> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original) >> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Feb 8 03:29:13 >> 2016 >> @@ -1434,6 +1434,8 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, >> } >> }) >> >> +DEF_TRAVERSE_DECL(OMPCapturedFieldDecl, { TRY_TO(TraverseVarHelper(D)); >> }) >> + >> // A helper method for TemplateDecl's children. >> template <typename Derived> >> bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper( >> >> Modified: cfe/trunk/include/clang/Basic/DeclNodes.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/DeclNodes.td (original) >> +++ cfe/trunk/include/clang/Basic/DeclNodes.td Mon Feb 8 03:29:13 2016 >> @@ -51,6 +51,7 @@ def Named : Decl<1>; >> : DDecl<VarTemplateSpecialization>; >> def ImplicitParam : DDecl<Var>; >> def ParmVar : DDecl<Var>; >> + def OMPCapturedField : DDecl<Var>; >> def NonTypeTemplateParm : DDecl<Declarator>; >> def Template : DDecl<Named, 1>; >> def RedeclarableTemplate : DDecl<Template, 1>; >> >> Modified: cfe/trunk/include/clang/Sema/Sema.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/include/clang/Sema/Sema.h (original) >> +++ cfe/trunk/include/clang/Sema/Sema.h Mon Feb 8 03:29:13 2016 >> @@ -7789,7 +7789,9 @@ public: >> /// \brief Check if the specified variable is used in one of the >> private >> /// clauses (private, firstprivate, lastprivate, reduction etc.) in >> OpenMP >> /// constructs. >> - bool IsOpenMPCapturedDecl(ValueDecl *D); >> + VarDecl *IsOpenMPCapturedDecl(ValueDecl *D); >> + ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, >> + ExprObjectKind OK); >> >> /// \brief Check if the specified variable is used in 'private' clause. >> /// \param Level Relative level of nested OpenMP construct for that >> the check >> >> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original) >> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon Feb 8 >> 03:29:13 2016 >> @@ -1163,6 +1163,8 @@ namespace clang { >> DECL_EMPTY, >> /// \brief An ObjCTypeParamDecl record. >> DECL_OBJC_TYPE_PARAM, >> + /// \brief An OMPCapturedFieldDecl record. >> + DECL_OMP_CAPTUREDFIELD, >> }; >> >> /// \brief Record codes for each kind of statement or expression. >> >> Modified: cfe/trunk/lib/AST/DeclBase.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/AST/DeclBase.cpp (original) >> +++ cfe/trunk/lib/AST/DeclBase.cpp Mon Feb 8 03:29:13 2016 >> @@ -655,6 +655,7 @@ unsigned Decl::getIdentifierNamespaceFor >> case ObjCCategoryImpl: >> case Import: >> case OMPThreadPrivate: >> + case OMPCapturedField: >> case Empty: >> // Never looked up by name. >> return 0; >> >> Modified: cfe/trunk/lib/AST/DeclOpenMP.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclOpenMP.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/AST/DeclOpenMP.cpp (original) >> +++ cfe/trunk/lib/AST/DeclOpenMP.cpp Mon Feb 8 03:29:13 2016 >> @@ -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(Array >> 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()); >> +} >> + >> >> Modified: cfe/trunk/lib/AST/DeclPrinter.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/AST/DeclPrinter.cpp (original) >> +++ cfe/trunk/lib/AST/DeclPrinter.cpp Mon Feb 8 03:29:13 2016 >> @@ -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::VisitOMPThreadPrivateD >> } >> } >> >> +void DeclPrinter::VisitOMPCapturedFieldDecl(OMPCapturedFieldDecl *D) { >> + D->getInit()->printPretty(Out, nullptr, Policy, Indentation); >> +} >> + >> >> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original) >> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Feb 8 03:29:13 2016 >> @@ -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); >> - } >> } >> } >> >> >> Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) >> +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Feb 8 03:29:13 2016 >> @@ -92,6 +92,7 @@ void CodeGenFunction::EmitDecl(const Dec >> 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; >> >> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Feb 8 03:29:13 2016 >> @@ -2874,6 +2874,7 @@ ExprResult Sema::BuildDeclarationNameExp >> 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() && >> >> Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaExprMember.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaExprMember.cpp Mon Feb 8 03:29:13 2016 >> @@ -1735,9 +1735,19 @@ BuildFieldReferenceExpr(Sema &S, Expr *B >> 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 >> >> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Feb 8 03:29:13 2016 >> @@ -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::getDS >> // 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::getParentLoopCont >> 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::getTo >> 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(ValueDe >> 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(ValueDec >> 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(ValueDec >> (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::ActOnOpenMPVarListClaus >> 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::ActOnOpenMPPrivateClaus >> 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); >> } >> >> >> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Feb 8 >> 03:29:13 2016 >> @@ -2483,6 +2483,11 @@ Decl *TemplateDeclInstantiator::VisitOMP >> return TD; >> } >> >> +Decl *TemplateDeclInstantiator::VisitOMPCapturedFieldDecl( >> + OMPCapturedFieldDecl * /*D*/) { >> + llvm_unreachable("Should not be met in templates"); >> +} >> + >> Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { >> return VisitFunctionDecl(D, nullptr); >> } >> >> Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Serialization/ASTCommon.cpp (original) >> +++ cfe/trunk/lib/Serialization/ASTCommon.cpp Mon Feb 8 03:29:13 2016 >> @@ -329,6 +329,7 @@ bool serialization::isRedeclarableDeclKi >> case Decl::ClassScopeFunctionSpecialization: >> case Decl::Import: >> case Decl::OMPThreadPrivate: >> + case Decl::OMPCapturedField: >> case Decl::BuiltinTemplate: >> return false; >> >> >> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) >> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon Feb 8 03:29:13 2016 >> @@ -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::VisitOMPThreadPrivat >> D->setVars(Vars); >> } >> >> +void ASTDeclReader::VisitOMPCapturedFieldDecl(OMPCapturedFieldDecl *D) { >> + VisitVarDecl(D); >> +} >> + >> >> >> //===----------------------------------------------------------------------===// >> // Attribute Reading >> >> >> //===----------------------------------------------------------------------===// >> @@ -3323,6 +3328,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID I >> 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; >> >> Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) >> +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon Feb 8 03:29:13 2016 >> @@ -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::VisitOMPThreadPrivat >> Code = serialization::DECL_OMP_THREADPRIVATE; >> } >> >> +void ASTDeclWriter::VisitOMPCapturedFieldDecl(OMPCapturedFieldDecl *D) { >> + VisitVarDecl(D); >> + Code = serialization::DECL_OMP_CAPTUREDFIELD; >> +} >> + >> >> >> //===----------------------------------------------------------------------===// >> // ASTWriter Implementation >> >> >> //===----------------------------------------------------------------------===// >> >> Modified: cfe/trunk/test/OpenMP/parallel_private_codegen.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_private_codegen.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/OpenMP/parallel_private_codegen.cpp (original) >> +++ cfe/trunk/test/OpenMP/parallel_private_codegen.cpp Mon Feb 8 >> 03:29:13 2016 >> @@ -18,11 +18,69 @@ struct S { >> >> volatile int g __attribute__((aligned(128))) = 1212; >> >> +struct SS { >> + int a; >> + int b : 4; >> + int &c; >> + SS(int &d) : a(0), b(0), c(d) { >> +#pragma omp parallel private(a, b, c) >> +#ifdef LAMBDA >> + [&]() { >> + ++this->a, --b, (this)->c /= 1; >> +#pragma omp parallel private(a, b, c) >> + ++(this)->a, --b, this->c /= 1; >> + }(); >> +#elif defined(BLOCKS) >> + ^{ >> + ++a; >> + --this->b; >> + (this)->c /= 1; >> +#pragma omp parallel private(a, b, c) >> + ++(this)->a, --b, this->c /= 1; >> + }(); >> +#else >> + ++this->a, --b, c /= 1; >> +#endif >> + } >> +}; >> + >> +template<typename T> >> +struct SST { >> + T a; >> + SST() : a(T()) { >> +#pragma omp parallel private(a) >> +#ifdef LAMBDA >> + [&]() { >> + [&]() { >> + ++this->a; >> +#pragma omp parallel private(a) >> + ++(this)->a; >> + }(); >> + }(); >> +#elif defined(BLOCKS) >> + ^{ >> + ^{ >> + ++a; >> +#pragma omp parallel private(a) >> + ++(this)->a; >> + }(); >> + }(); >> +#else >> + ++(this)->a; >> +#endif >> + } >> +}; >> + >> +// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 >> +// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 >> +// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 >> // CHECK: [[S_FLOAT_TY:%.+]] = type { float } >> // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } >> +// CHECK: [[SST_TY:%.+]] = type { i{{[0-9]+}} } >> template <typename T> >> T tmain() { >> S<T> test; >> + SST<T> sst; >> T t_var __attribute__((aligned(128))) = T(); >> T vec[] __attribute__((aligned(128))) = {1, 2}; >> S<T> s_arr[] __attribute__((aligned(128))) = {1, 2}; >> @@ -37,9 +95,11 @@ T tmain() { >> >> int main() { >> static int sivar; >> + SS ss(sivar); >> #ifdef LAMBDA >> // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, >> // LAMBDA-LABEL: @main >> + // LAMBDA: call >> // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( >> [&]() { >> // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( >> @@ -47,6 +107,36 @@ int main() { >> // LAMBDA: call{{.*}} void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, >> {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) >> #pragma omp parallel private(g, sivar) >> { >> + // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]* % >> + // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* % >> + // LAMBDA: store i8 >> + // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, >> i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} >> 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, >> i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void >> + // LAMBDA: ret >> + >> + // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* >> noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) >> + // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % >> + // LAMBDA: call{{.*}} void >> + // LAMBDA: ret void >> + >> + // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias >> [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) >> + // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, >> + // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, >> + // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, >> + // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], >> + // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], >> + // LAMBDA-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** >> [[REFA]], >> + // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* >> [[A_PRIV]], >> + // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 >> + // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], >> + // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* >> [[B_PRIV]], >> + // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 >> + // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], >> + // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** >> [[REFC]], >> + // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* >> [[C_PRIV]], >> + // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 >> + // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], >> + // LAMBDA-NEXT: ret void >> + >> // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* >> noalias %{{.+}}, i32* noalias %{{.+}}) >> // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, >> // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, >> @@ -80,6 +170,7 @@ int main() { >> #elif defined(BLOCKS) >> // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, >> // BLOCKS-LABEL: @main >> + // BLOCKS: call >> // BLOCKS: call{{.*}} void {{%.+}}(i8 >> ^{ >> // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* >> @@ -116,6 +207,35 @@ int main() { >> } >> }(); >> return 0; >> +// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]* % >> +// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* % >> +// BLOCKS: store i8 >> +// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, >> i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} >> 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, >> i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void >> +// BLOCKS: ret >> + >> +// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias >> [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) >> +// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % >> +// BLOCKS: call{{.*}} void >> +// BLOCKS: ret void >> + >> +// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias >> [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) >> +// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, >> +// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, >> +// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, >> +// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], >> +// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], >> +// BLOCKS-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** >> [[REFA]], >> +// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* >> [[A_PRIV]], >> +// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 >> +// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], >> +// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* >> [[B_PRIV]], >> +// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 >> +// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], >> +// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** >> [[REFC]], >> +// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* >> [[C_PRIV]], >> +// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 >> +// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], >> +// BLOCKS-NEXT: ret void >> #else >> S<float> test; >> int t_var = 0; >> @@ -166,6 +286,31 @@ int main() { >> // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* >> // CHECK: ret >> // >> +// CHECK: define {{.+}} @{{.+}}([[SS_TY]]* % >> +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % >> +// CHECK: store i8 >> +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, >> i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} >> 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, >> i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void >> +// CHECK: ret >> + >> +// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias >> [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) >> +// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, >> +// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, >> +// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, >> +// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], >> +// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], >> +// CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** >> [[REFA]], >> +// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], >> +// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 >> +// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], >> +// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], >> +// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 >> +// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], >> +// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** >> [[REFC]], >> +// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], >> +// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 >> +// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], >> +// CHECK-NEXT: ret void >> + >> // CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias >> [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) >> // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 >> // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128 >> @@ -184,5 +329,20 @@ int main() { >> // CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) >> // CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* >> // CHECK: ret void >> + >> +// CHECK: define {{.+}} @{{.+}}([[SST_TY]]* % >> +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % >> +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, >> i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} >> 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, >> i{{[0-9]+}}*, [[SST_TY]]*)* [[SST_MICROTASK:@.+]] to void >> +// CHECK: ret >> + >> +// CHECK: define internal void [[SST_MICROTASK]](i{{[0-9]+}}* noalias >> [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SST_TY]]* %{{.+}}) >> +// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, >> +// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REF:%.+]], >> +// CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REF]], >> +// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], >> +// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 >> +// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], >> +// CHECK-NEXT: ret void >> + >> #endif >> >> >> Modified: cfe/trunk/tools/libclang/CIndex.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=260077&r1=260076&r2=260077&view=diff >> >> ============================================================================== >> --- cfe/trunk/tools/libclang/CIndex.cpp (original) >> +++ cfe/trunk/tools/libclang/CIndex.cpp Mon Feb 8 03:29:13 2016 >> @@ -5669,6 +5669,7 @@ CXCursor clang_getCursorDefinition(CXCur >> case Decl::StaticAssert: >> case Decl::Block: >> case Decl::Captured: >> + case Decl::OMPCapturedField: >> case Decl::Label: // FIXME: Is this right?? >> case Decl::ClassScopeFunctionSpecialization: >> case Decl::Import: >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits