r260077 - [OPENMP 4.5] Ccapture/codegen of private non-static data members.
Renato Golin via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 9 03:07:35 PST 2016
Hi Alexey,
It's still broken on ARM:
http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-full/builds/10409
cheers,
--renato
On 8 February 2016 at 14:25, Alexey Bataev via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
> Ok, thanks a lot! Hope it will fix win-based buildbots completely.
>
> Best regards,
> Alexey Bataev
> =============
> Software Engineer
> Intel Compiler Team
>
> 08.02.2016 17:11, NAKAMURA Takumi пишет:
>
> 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.bataev at 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 at 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 at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list