r260077 - [OPENMP 4.5] Ccapture/codegen of private non-static data members.
NAKAMURA Takumi via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 8 06:11:37 PST 2016
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
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160208/3053a1c2/attachment-0001.html>
More information about the cfe-commits
mailing list