r260077 - [OPENMP 4.5] Ccapture/codegen of private non-static data members.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 9 03:42:49 PST 2016


Renato,
Will be fixed ASAP

Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team

09.02.2016 14:07, Renato Golin пишет:
> 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