<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Yes, thanks for fixing this, David!<br>
      <pre class="moz-signature" cols="72">Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team</pre>
      01.01.2015 12:51, David Majnemer пишет:<br>
    </div>
    <blockquote
cite="mid:CAL7bZ_dCqEARXqFvHF5JFFPvR5pECiCNYpbgmPUHFqteC7Qcpg@mail.gmail.com"
      type="cite">
      <div dir="ltr">Should be fixed with r225060.</div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Wed, Dec 31, 2014 at 6:11 PM, David
          Majnemer <span dir="ltr"><<a moz-do-not-send="true"
              href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div dir="ltr">It looks like this caused PR22071,
              reverting r224323 makes the crash go away.</div>
            <div class="HOEnZb">
              <div class="h5">
                <div class="gmail_extra"><br>
                  <div class="gmail_quote">On Mon, Dec 15, 2014 at 11:00
                    PM, Alexey Bataev <span dir="ltr"><<a
                        moz-do-not-send="true"
                        href="mailto:a.bataev@hotmail.com"
                        target="_blank">a.bataev@hotmail.com</a>></span>
                    wrote:<br>
                    <blockquote class="gmail_quote" style="margin:0 0 0
                      .8ex;border-left:1px #ccc solid;padding-left:1ex">Author:
                      abataev<br>
                      Date: Tue Dec 16 01:00:22 2014<br>
                      New Revision: 224323<br>
                      <br>
                      URL: <a moz-do-not-send="true"
                        href="http://llvm.org/viewvc/llvm-project?rev=224323&view=rev"
                        target="_blank">http://llvm.org/viewvc/llvm-project?rev=224323&view=rev</a><br>
                      Log:<br>
                      [OPENMP] Bugfix for processing of global variables
                      in OpenMP regions.<br>
                      Currently, if global variable is marked as a
                      private OpenMP variable, the compiler crashes in
                      debug version or generates incorrect code in
                      release version. It happens because in the OpenMP
                      region the original global variable is used
                      instead of the generated private copy. It happens
                      because currently globals variables are not
                      captured in the OpenMP region.<br>
                      This patch adds capturing of global variables iff
                      private copy of the global variable must be used
                      in the OpenMP region.<br>
                      Differential Revision: <a moz-do-not-send="true"
                        href="http://reviews.llvm.org/D6259"
                        target="_blank">http://reviews.llvm.org/D6259</a><br>
                      <br>
                      Modified:<br>
                          cfe/trunk/include/clang/Sema/Sema.h<br>
                          cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
                          cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
                          cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
                         
                      cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp<br>
                          cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp<br>
                          cfe/trunk/lib/Sema/SemaExpr.cpp<br>
                          cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
                         
                      cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp<br>
                         
                      cfe/trunk/test/OpenMP/parallel_private_codegen.cpp<br>
                      <br>
                      Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      --- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
                      +++ cfe/trunk/include/clang/Sema/Sema.h Tue Dec 16
                      01:00:22 2014<br>
                      @@ -3448,6 +3448,9 @@ public:<br>
                                                 TryCaptureKind Kind =
                      TryCapture_Implicit,<br>
                                                 SourceLocation
                      EllipsisLoc = SourceLocation());<br>
                      <br>
                      +  /// \brief Checks if the variable must be
                      captured.<br>
                      +  bool NeedToCaptureVariable(VarDecl *Var,
                      SourceLocation Loc);<br>
                      +<br>
                         /// \brief Given a variable, determine the type
                      that a reference to that<br>
                         /// variable will have in the given scope.<br>
                         QualType getCapturedDeclRefType(VarDecl *Var,
                      SourceLocation Loc);<br>
                      @@ -7482,6 +7485,10 @@ private:<br>
                         void DestroyDataSharingAttributesStack();<br>
                         ExprResult
                      VerifyPositiveIntegerConstantInClause(Expr *Op,<br>
                                                                       
                        OpenMPClauseKind CKind);<br>
                      +  /// \brief Checks if the specified variable is
                      used in one of the private<br>
                      +  /// clauses in OpenMP constructs.<br>
                      +  bool IsOpenMPCapturedVar(VarDecl *VD);<br>
                      +<br>
                       public:<br>
                         ExprResult
                      PerformOpenMPImplicitIntegerConversion(SourceLocation
                      OpLoc,<br>
                                                                       
                         Expr *Op);<br>
                      <br>
                      Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br>
                      +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Dec 16
                      01:00:22 2014<br>
                      @@ -1906,6 +1906,21 @@ LValue
                      CodeGenFunction::EmitDeclRefLValu<br>
                         QualType T = E->getType();<br>
                      <br>
                         if (const auto *VD =
                      dyn_cast<VarDecl>(ND)) {<br>
                      +    // Check for captured variables.<br>
                      +    if (E->refersToEnclosingLocal()) {<br>
                      +      if (auto *FD =
                      LambdaCaptureFields.lookup(VD))<br>
                      +        return EmitCapturedFieldLValue(*this, FD,
                      CXXABIThisValue);<br>
                      +      else if (CapturedStmtInfo) {<br>
                      +        if (auto *V = LocalDeclMap.lookup(VD))<br>
                      +          return MakeAddrLValue(V, T, Alignment);<br>
                      +        else<br>
                      +          return EmitCapturedFieldLValue(*this,
                      CapturedStmtInfo->lookup(VD),<br>
                      +                                       
                       CapturedStmtInfo->getContextValue());<br>
                      +      } else<br>
                      +        return
                      MakeAddrLValue(GetAddrOfBlockDecl(VD,
                      VD->hasAttr<BlocksAttr>()),<br>
                      +                              T, Alignment);<br>
                      +    }<br>
                      +<br>
                           // Global Named registers access via
                      intrinsics only<br>
                           if (VD->getStorageClass() == SC_Register
                      &&<br>
                               VD->hasAttr<AsmLabelAttr>()
                      && !VD->isLocalVarDecl())<br>
                      @@ -1956,21 +1971,6 @@ LValue
                      CodeGenFunction::EmitDeclRefLValu<br>
                                 *this, VD, T, V,
                      getTypes().ConvertTypeForMem(VD->getType()),<br>
                                 Alignment, E->getExprLoc());<br>
                      <br>
                      -    // Use special handling for lambdas.<br>
                      -    if (!V) {<br>
                      -      if (FieldDecl *FD =
                      LambdaCaptureFields.lookup(VD)) {<br>
                      -        return EmitCapturedFieldLValue(*this, FD,
                      CXXABIThisValue);<br>
                      -      } else if (CapturedStmtInfo) {<br>
                      -        if (const FieldDecl *FD =
                      CapturedStmtInfo->lookup(VD))<br>
                      -          return EmitCapturedFieldLValue(*this,
                      FD,<br>
                      -                                       
                       CapturedStmtInfo->getContextValue());<br>
                      -      }<br>
                      -<br>
                      -      assert(isa<BlockDecl>(CurCodeDecl)
                      && E->refersToEnclosingLocal());<br>
                      -      return
                      MakeAddrLValue(GetAddrOfBlockDecl(VD,
                      isBlockVariable),<br>
                      -                            T, Alignment);<br>
                      -    }<br>
                      -<br>
                           assert(V && "DeclRefExpr not entered
                      in LocalDeclMap?");<br>
                      <br>
                           if (isBlockVariable)<br>
                      <br>
                      Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
                      (original)<br>
                      +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Dec
                      16 01:00:22 2014<br>
                      @@ -20,6 +20,35 @@<br>
                       using namespace clang;<br>
                       using namespace CodeGen;<br>
                      <br>
                      +namespace {<br>
                      +/// \brief RAII for emitting code of CapturedStmt
                      without function outlining.<br>
                      +class InlinedOpenMPRegion {<br>
                      +  CodeGenFunction &CGF;<br>
                      +  CodeGenFunction::CGCapturedStmtInfo
                      *PrevCapturedStmtInfo;<br>
                      +  const Decl *StoredCurCodeDecl;<br>
                      +<br>
                      +  /// \brief A class to emit CapturedStmt
                      construct as inlined statement without<br>
                      +  /// generating a function for outlined code.<br>
                      +  class CGInlinedOpenMPRegionInfo : public
                      CodeGenFunction::CGCapturedStmtInfo {<br>
                      +  public:<br>
                      +    CGInlinedOpenMPRegionInfo() :
                      CGCapturedStmtInfo() {}<br>
                      +  };<br>
                      +<br>
                      +public:<br>
                      +  InlinedOpenMPRegion(CodeGenFunction &CGF,
                      const Stmt *S)<br>
                      +      : CGF(CGF),
                      PrevCapturedStmtInfo(CGF.CapturedStmtInfo),<br>
                      +        StoredCurCodeDecl(CGF.CurCodeDecl) {<br>
                      +    CGF.CurCodeDecl =
                      cast<CapturedStmt>(S)->getCapturedDecl();<br>
                      +    CGF.CapturedStmtInfo = new
                      CGInlinedOpenMPRegionInfo();<br>
                      +  }<br>
                      +  ~InlinedOpenMPRegion() {<br>
                      +    delete CGF.CapturedStmtInfo;<br>
                      +    CGF.CapturedStmtInfo = PrevCapturedStmtInfo;<br>
                      +    CGF.CurCodeDecl = StoredCurCodeDecl;<br>
                      +  }<br>
                      +};<br>
                      +} // namespace<br>
                      +<br>
 //===----------------------------------------------------------------------===//<br>
                       //                              OpenMP Directive
                      Emission<br>
 //===----------------------------------------------------------------------===//<br>
                      @@ -417,6 +446,7 @@ void
                      CodeGenFunction::EmitOMPSimdDirecti<br>
                           }<br>
                         }<br>
                      <br>
                      +  InlinedOpenMPRegion Region(*this,
                      S.getAssociatedStmt());<br>
                         RunCleanupsScope DirectiveScope(*this);<br>
                      <br>
                         CGDebugInfo *DI = getDebugInfo();<br>
                      @@ -561,6 +591,7 @@ void
                      CodeGenFunction::EmitOMPWorksharing<br>
                       }<br>
                      <br>
                       void CodeGenFunction::EmitOMPForDirective(const
                      OMPForDirective &S) {<br>
                      +  InlinedOpenMPRegion Region(*this,
                      S.getAssociatedStmt());<br>
                         RunCleanupsScope DirectiveScope(*this);<br>
                      <br>
                         CGDebugInfo *DI = getDebugInfo();<br>
                      @@ -593,8 +624,8 @@ void
                      CodeGenFunction::EmitOMPSingleDirec<br>
                       }<br>
                      <br>
                       void
                      CodeGenFunction::EmitOMPMasterDirective(const
                      OMPMasterDirective &S) {<br>
                      -  CGM.getOpenMPRuntime().EmitOMPMasterRegion(<br>
                      -      *this, [&]() -> void {<br>
                      + 
                      CGM.getOpenMPRuntime().EmitOMPMasterRegion(*this,
                      [&]() -> void {<br>
                      +    InlinedOpenMPRegion Region(*this,
                      S.getAssociatedStmt());<br>
                           RunCleanupsScope Scope(*this);<br>
                         
 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());<br>
                           EnsureInsertPoint();<br>
                      @@ -604,8 +635,10 @@ void
                      CodeGenFunction::EmitOMPMasterDirec<br>
                       void
                      CodeGenFunction::EmitOMPCriticalDirective(const
                      OMPCriticalDirective &S) {<br>
                         CGM.getOpenMPRuntime().EmitOMPCriticalRegion(<br>
                             *this, S.getDirectiveName().getAsString(),
                      [&]() -> void {<br>
                      +    InlinedOpenMPRegion Region(*this,
                      S.getAssociatedStmt());<br>
                           RunCleanupsScope Scope(*this);<br>
                      -   
EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());<br>
                      +    EmitStmt(<br>
                      +       
                      cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());<br>
                           EnsureInsertPoint();<br>
                         }, S.getLocStart());<br>
                       }<br>
                      <br>
                      Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      --- cfe/trunk/lib/CodeGen/CodeGenFunction.h
                      (original)<br>
                      +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue
                      Dec 16 01:00:22 2014<br>
                      @@ -182,6 +182,8 @@ public:<br>
                         /// \brief API for captured statement code
                      generation.<br>
                         class CGCapturedStmtInfo {<br>
                         public:<br>
                      +    explicit
                      CGCapturedStmtInfo(CapturedRegionKind K =
                      CR_Default)<br>
                      +        : Kind(K), ThisValue(nullptr),
                      CXXThisFieldDecl(nullptr) {}<br>
                           explicit CGCapturedStmtInfo(const
                      CapturedStmt &S,<br>
                                                     
                       CapturedRegionKind K = CR_Default)<br>
                             : Kind(K), ThisValue(nullptr),
                      CXXThisFieldDecl(nullptr) {<br>
                      @@ -614,7 +616,6 @@ public:<br>
                           addPrivate(const VarDecl *LocalVD,<br>
                                      const std::function<llvm::Value
                      *()> &PrivateGen) {<br>
                             assert(PerformCleanup && "adding
                      private to dead scope");<br>
                      -      assert(LocalVD->isLocalVarDecl()
                      && "privatizing non-local variable");<br>
                             if (SavedLocals.count(LocalVD) > 0)
                      return false;<br>
                             SavedLocals[LocalVD] =
                      CGF.LocalDeclMap.lookup(LocalVD);<br>
                             CGF.LocalDeclMap.erase(LocalVD);<br>
                      <br>
                      Modified:
                      cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      ---
                      cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp
                      (original)<br>
                      +++
                      cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp
                      Tue Dec 16 01:00:22 2014<br>
                      @@ -4563,16 +4563,12 @@ void
                      RewriteModernObjC::GetBlockDeclRefE<br>
                               GetBlockDeclRefExprs(*CI);<br>
                           }<br>
                         // Handle specific things.<br>
                      -  if (DeclRefExpr *DRE =
                      dyn_cast<DeclRefExpr>(S)) {<br>
                      -    if (DRE->refersToEnclosingLocal()) {<br>
                      +  if (DeclRefExpr *DRE =
                      dyn_cast<DeclRefExpr>(S))<br>
                      +    if (DRE->refersToEnclosingLocal() ||<br>
                      +       
                      HasLocalVariableExternalStorage(DRE->getDecl()))<br>
                             // FIXME: Handle enums.<br>
                      -      if
                      (!isa<FunctionDecl>(DRE->getDecl()))<br>
                      -        BlockDeclRefs.push_back(DRE);<br>
                      -      if
                      (HasLocalVariableExternalStorage(DRE->getDecl()))<br>
                      -        BlockDeclRefs.push_back(DRE);<br>
                      -    }<br>
                      -  }<br>
                      -<br>
                      +      BlockDeclRefs.push_back(DRE);<br>
                      +<br>
                         return;<br>
                       }<br>
                      <br>
                      @@ -4595,11 +4591,11 @@ void
                      RewriteModernObjC::GetInnerBlockDec<br>
                           }<br>
                         // Handle specific things.<br>
                         if (DeclRefExpr *DRE =
                      dyn_cast<DeclRefExpr>(S)) {<br>
                      -    if (DRE->refersToEnclosingLocal()) {<br>
                      -      if
                      (!isa<FunctionDecl>(DRE->getDecl())
                      &&<br>
                      -         
                      !InnerContexts.count(DRE->getDecl()->getDeclContext()))<br>
                      +    if (DRE->refersToEnclosingLocal() ||<br>
                      +       
                      HasLocalVariableExternalStorage(DRE->getDecl()))
                      {<br>
                      +      if
                      (!InnerContexts.count(DRE->getDecl()->getDeclContext()))<br>
                               InnerBlockDeclRefs.push_back(DRE);<br>
                      -      if (VarDecl *Var =
                      dyn_cast<VarDecl>(DRE->getDecl()))<br>
                      +      if (VarDecl *Var =
                      cast<VarDecl>(DRE->getDecl()))<br>
                               if (Var->isFunctionOrMethodVarDecl())<br>
                                 ImportedLocalExternalDecls.insert(Var);<br>
                           }<br>
                      @@ -4776,7 +4772,8 @@ Stmt
                      *RewriteModernObjC::RewriteBlockDec<br>
                         // Rewrite the byref variable into
                      BYREFVAR->__forwarding->BYREFVAR<br>
                         // for each DeclRefExp where BYREFVAR is name
                      of the variable.<br>
                         ValueDecl *VD = DeclRefExp->getDecl();<br>
                      -  bool isArrow =
                      DeclRefExp->refersToEnclosingLocal();<br>
                      +  bool isArrow =
                      DeclRefExp->refersToEnclosingLocal() ||<br>
                      +               
                       HasLocalVariableExternalStorage(DeclRefExp->getDecl());<br>
                      <br>
                         FieldDecl *FD = FieldDecl::Create(*Context,
                      nullptr, SourceLocation(),<br>
                                                         
                       SourceLocation(),<br>
                      <br>
                      Modified:
                      cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      --- cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp
                      (original)<br>
                      +++ cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp
                      Tue Dec 16 01:00:22 2014<br>
                      @@ -3671,16 +3671,12 @@ void
                      RewriteObjC::GetBlockDeclRefExprs(S<br>
                               GetBlockDeclRefExprs(*CI);<br>
                           }<br>
                         // Handle specific things.<br>
                      -  if (DeclRefExpr *DRE =
                      dyn_cast<DeclRefExpr>(S)) {<br>
                      -    if (DRE->refersToEnclosingLocal()) {<br>
                      +  if (DeclRefExpr *DRE =
                      dyn_cast<DeclRefExpr>(S))<br>
                      +    if (DRE->refersToEnclosingLocal() ||<br>
                      +       
                      HasLocalVariableExternalStorage(DRE->getDecl()))<br>
                             // FIXME: Handle enums.<br>
                      -      if
                      (!isa<FunctionDecl>(DRE->getDecl()))<br>
                      -        BlockDeclRefs.push_back(DRE);<br>
                      -      if
                      (HasLocalVariableExternalStorage(DRE->getDecl()))<br>
                      -        BlockDeclRefs.push_back(DRE);<br>
                      -    }<br>
                      -  }<br>
                      -<br>
                      +      BlockDeclRefs.push_back(DRE);<br>
                      +<br>
                         return;<br>
                       }<br>
                      <br>
                      @@ -3703,11 +3699,11 @@ void
                      RewriteObjC::GetInnerBlockDeclRefEx<br>
                           }<br>
                         // Handle specific things.<br>
                         if (DeclRefExpr *DRE =
                      dyn_cast<DeclRefExpr>(S)) {<br>
                      -    if (DRE->refersToEnclosingLocal()) {<br>
                      -      if
                      (!isa<FunctionDecl>(DRE->getDecl())
                      &&<br>
                      -         
                      !InnerContexts.count(DRE->getDecl()->getDeclContext()))<br>
                      +    if (DRE->refersToEnclosingLocal() ||<br>
                      +       
                      HasLocalVariableExternalStorage(DRE->getDecl()))
                      {<br>
                      +      if
                      (!InnerContexts.count(DRE->getDecl()->getDeclContext()))<br>
                               InnerBlockDeclRefs.push_back(DRE);<br>
                      -      if (VarDecl *Var =
                      dyn_cast<VarDecl>(DRE->getDecl()))<br>
                      +      if (VarDecl *Var =
                      cast<VarDecl>(DRE->getDecl()))<br>
                               if (Var->isFunctionOrMethodVarDecl())<br>
                                 ImportedLocalExternalDecls.insert(Var);<br>
                           }<br>
                      @@ -3865,7 +3861,8 @@ Stmt
                      *RewriteObjC::RewriteBlockDeclRefEx<br>
                         // Rewrite the byref variable into
                      BYREFVAR->__forwarding->BYREFVAR<br>
                         // for each DeclRefExp where BYREFVAR is name
                      of the variable.<br>
                         ValueDecl *VD = DeclRefExp->getDecl();<br>
                      -  bool isArrow =
                      DeclRefExp->refersToEnclosingLocal();<br>
                      +  bool isArrow =
                      DeclRefExp->refersToEnclosingLocal() ||<br>
                      +               
                       HasLocalVariableExternalStorage(DeclRefExp->getDecl());<br>
                      <br>
                         FieldDecl *FD = FieldDecl::Create(*Context,
                      nullptr, SourceLocation(),<br>
                                                         
                       SourceLocation(),<br>
                      <br>
                      Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
                      +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Dec 16
                      01:00:22 2014<br>
                      @@ -1602,10 +1602,8 @@
                      Sema::BuildDeclRefExpr(ValueDecl *D, Qua<br>
                             }<br>
                      <br>
                         bool refersToEnclosingScope =<br>
                      -    (CurContext != D->getDeclContext()
                      &&<br>
                      -   
                       D->getDeclContext()->isFunctionOrMethod())
                      ||<br>
                      -    (isa<VarDecl>(D) &&<br>
                      -     cast<VarDecl>(D)->isInitCapture());<br>
                      +      isa<VarDecl>(D) &&<br>
                      +     
                      NeedToCaptureVariable(cast<VarDecl>(D),
                      NameInfo.getLoc());<br>
                      <br>
                         DeclRefExpr *E;<br>
                         if
                      (isa<VarTemplateSpecializationDecl>(D)) {<br>
                      @@ -11799,7 +11797,7 @@ static DeclContext
                      *getParentOfCapturing<br>
                                                        const bool
                      Diagnose, Sema &S) {<br>
                         if (isa<BlockDecl>(DC) ||
                      isa<CapturedDecl>(DC) ||
                      isLambdaCallOperator(DC))<br>
                           return getLambdaAwareParentOfDeclContext(DC);<br>
                      -  else {<br>
                      +  else if (Var->hasLocalStorage()) {<br>
                           if (Diagnose)<br>
                              diagnoseUncapturableValueReference(S, Loc,
                      Var, DC);<br>
                         }<br>
                      @@ -12241,7 +12239,7 @@ bool
                      Sema::tryCaptureVariable(VarDecl *V<br>
                                                     QualType
                      &CaptureType,<br>
                                                     QualType
                      &DeclRefType,<br>
                                                                       
                                    const unsigned *const
                      FunctionScopeIndexToStopAt) {<br>
                      -  bool Nested = false;<br>
                      +  bool Nested = Var->isInitCapture();<br>
                      <br>
                         DeclContext *DC = CurContext;<br>
                         const unsigned MaxFunctionScopesIndex =
                      FunctionScopeIndexToStopAt<br>
                      @@ -12259,8 +12257,13 @@ bool
                      Sema::tryCaptureVariable(VarDecl *V<br>
                      <br>
                         // If the variable is declared in the current
                      context (and is not an<br>
                         // init-capture), there is no need to capture
                      it.<br>
                      -  if (!Var->isInitCapture() &&
                      Var->getDeclContext() == DC) return true;<br>
                      -  if (!Var->hasLocalStorage()) return true;<br>
                      +  if (!Nested && Var->getDeclContext()
                      == DC) return true;<br>
                      +<br>
                      +  // Capture global variables if it is required
                      to use private copy of this<br>
                      +  // variable.<br>
                      +  bool IsGlobal = !Var->hasLocalStorage();<br>
                      +  if (IsGlobal && !(LangOpts.OpenMP
                      && IsOpenMPCapturedVar(Var)))<br>
                      +    return true;<br>
                      <br>
                         // Walk up the stack to determine whether we
                      can capture the variable,<br>
                         // performing the "simple" checks that don't
                      depend on type. We stop when<br>
                      @@ -12281,8 +12284,17 @@ bool
                      Sema::tryCaptureVariable(VarDecl *V<br>
                                                                       
                                   ExprLoc,<br>
                                                                       
                                   BuildAndDiagnose,<br>
                                                                       
                                   *this);<br>
                      -    if (!ParentDC) return true;<br>
                      -<br>
                      +    // We need to check for the parent *first*
                      because, if we *have*<br>
                      +    // private-captured a global variable, we
                      need to recursively capture it in<br>
                      +    // intermediate blocks, lambdas, etc.<br>
                      +    if (!ParentDC) {<br>
                      +      if (IsGlobal) {<br>
                      +        FunctionScopesIndex =
                      MaxFunctionScopesIndex - 1;<br>
                      +        break;<br>
                      +      }<br>
                      +      return true;<br>
                      +    }<br>
                      +<br>
                           FunctionScopeInfo  *FSI =
                      FunctionScopes[FunctionScopesIndex];<br>
                           CapturingScopeInfo *CSI =
                      cast<CapturingScopeInfo>(FSI);<br>
                      <br>
                      @@ -12508,6 +12520,14 @@ bool
                      Sema::tryCaptureVariable(VarDecl *V<br>
                                                   DeclRefType,
                      nullptr);<br>
                       }<br>
                      <br>
                      +bool Sema::NeedToCaptureVariable(VarDecl *Var,
                      SourceLocation Loc) {<br>
                      +  QualType CaptureType;<br>
                      +  QualType DeclRefType;<br>
                      +  return !tryCaptureVariable(Var, Loc,
                      TryCapture_Implicit, SourceLocation(),<br>
                      +                           
                       /*BuildAndDiagnose=*/false, CaptureType,<br>
                      +                             DeclRefType,
                      nullptr);<br>
                      +}<br>
                      +<br>
                       QualType Sema::getCapturedDeclRefType(VarDecl
                      *Var, SourceLocation Loc) {<br>
                         QualType CaptureType;<br>
                         QualType DeclRefType;<br>
                      <br>
                      Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
                      +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Dec 16
                      01:00:22 2014<br>
                      @@ -551,6 +551,19 @@ void
                      Sema::InitDataSharingAttributesStac<br>
                      <br>
                       #define DSAStack static_cast<DSAStackTy
                      *>(VarDataSharingAttributesStack)<br>
                      <br>
                      +bool Sema::IsOpenMPCapturedVar(VarDecl *VD) {<br>
                      +  assert(LangOpts.OpenMP && "OpenMP is
                      not allowed");<br>
                      +  if (DSAStack->getCurrentDirective() !=
                      OMPD_unknown) {<br>
                      +    auto DVarPrivate = DSAStack->getTopDSA(VD,
                      /*FromParent=*/false);<br>
                      +    if (DVarPrivate.CKind != OMPC_unknown
                      && isOpenMPPrivate(DVarPrivate.CKind))<br>
                      +      return true;<br>
                      +    DVarPrivate = DSAStack->hasDSA(VD,
                      isOpenMPPrivate, MatchesAlways(),<br>
                      +                                 
                       /*FromParent=*/false);<br>
                      +    return DVarPrivate.CKind != OMPC_unknown;<br>
                      +  }<br>
                      +  return false;<br>
                      +}<br>
                      +<br>
                       void Sema::DestroyDataSharingAttributesStack() {
                      delete DSAStack; }<br>
                      <br>
                       void
                      Sema::StartOpenMPDSABlock(OpenMPDirectiveKind
                      DKind,<br>
                      @@ -4378,7 +4391,7 @@ OMPClause
                      *Sema::ActOnOpenMPFirstprivate<br>
                             VDInitRefExpr = DeclRefExpr::Create(<br>
                                 Context, /*QualifierLoc*/
                      NestedNameSpecifierLoc(),<br>
                                 /*TemplateKWLoc*/ SourceLocation(),
                      VDInit,<br>
                      -          /*isEnclosingLocal*/ false, ELoc, Type,<br>
                      +          /*isEnclosingLocal*/ true, ELoc, Type,<br>
                                 /*VK*/ VK_LValue);<br>
                             VDInit->setIsUsed();<br>
                             auto Init =
                      DefaultLvalueConversion(VDInitRefExpr).get();<br>
                      @@ -4392,8 +4405,14 @@ OMPClause
                      *Sema::ActOnOpenMPFirstprivate<br>
                             else<br>
                             
                       VDPrivate->setInit(Result.getAs<Expr>());<br>
                           } else {<br>
                      -      AddInitializerToDecl(VDPrivate,
                      DefaultLvalueConversion(DE).get(),<br>
                      -                           /*DirectInit*/ false,
                      /*TypeMayContainAuto*/ false);<br>
                      +      AddInitializerToDecl(<br>
                      +          VDPrivate, DefaultLvalueConversion(<br>
                      +                       
                       DeclRefExpr::Create(Context,
                      NestedNameSpecifierLoc(),<br>
                      +                                           
                       SourceLocation(), DE->getDecl(),<br>
                      +                                           
                       /*isEnclosingLocal=*/true,<br>
                      +                                           
                       DE->getExprLoc(), DE->getType(),<br>
                      +                                           
                       /*VK=*/VK_LValue)).get(),<br>
                      +          /*DirectInit=*/false,
                      /*TypeMayContainAuto=*/false);<br>
                           }<br>
                           if (VDPrivate->isInvalidDecl()) {<br>
                             if (IsImplicitClause) {<br>
                      <br>
                      Modified:
                      cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      ---
                      cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
                      (original)<br>
                      +++
                      cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
                      Tue Dec 16 01:00:22 2014<br>
                      @@ -1,6 +1,8 @@<br>
                       // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x
                      c++ -triple %itanium_abi_triple -emit-llvm %s -o -
                      | FileCheck %s<br>
                       // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++
                      -std=c++11 -triple %itanium_abi_triple -emit-pch
                      -o %t %s<br>
                       // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++
                      -triple %itanium_abi_triple -std=c++11
                      -include-pch %t -verify %s -emit-llvm -o - |
                      FileCheck %s<br>
                      +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x
                      c++ -std=c++11 -DLAMBDA -triple
                      %itanium_abi_triple -emit-llvm %s -o - | FileCheck
                      -check-prefix=LAMBDA %s<br>
                      +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x
                      c++ -fblocks -DBLOCKS -triple %itanium_abi_triple
                      -emit-llvm %s -o - | FileCheck
                      -check-prefix=BLOCKS %s<br>
                       // expected-no-diagnostics<br>
                       #ifndef HEADER<br>
                       #define HEADER<br>
                      @@ -12,7 +14,7 @@ struct St {<br>
                         ~St() {}<br>
                       };<br>
                      <br>
                      -volatile int g;<br>
                      +volatile int g = 1212;<br>
                      <br>
                       template <class T><br>
                       struct S {<br>
                      @@ -47,6 +49,83 @@ T tmain() {<br>
                       }<br>
                      <br>
                       int main() {<br>
                      +#ifdef LAMBDA<br>
                      +  // LAMBDA: [[<a class="moz-txt-link-abbreviated" href="mailto:G:@.+">G:@.+</a>]] = global i{{[0-9]+}} 1212,<br>
                      +  // LAMBDA-LABEL: @main<br>
                      +  // LAMBDA: call void [[<a class="moz-txt-link-abbreviated" href="mailto:OUTER_LAMBDA:@.+">OUTER_LAMBDA:@.+</a>]](<br>
                      +  [&]() {<br>
                      +  // LAMBDA: define{{.*}} internal{{.*}} void
                      [[OUTER_LAMBDA]](<br>
                      +  // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr
                      inbounds %{{.+}}* [[AGG_CAPTURED:%.+]],
                      i{{[0-9]+}} 0, i{{[0-9]+}} 0<br>
                      +  // LAMBDA: store i{{[0-9]+}}* [[G]],
                      i{{[0-9]+}}** [[G_LOCAL_REF]]<br>
                      +  // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}*
                      [[AGG_CAPTURED]] to i8*<br>
                      +  // LAMBDA: call void {{.+}}*
                      @__kmpc_fork_call({{.+}}, i32 1, {{.+}}*
                      [[<a class="moz-txt-link-abbreviated" href="mailto:OMP_REGION:@.+">OMP_REGION:@.+</a>]] to {{.+}}, i8* [[ARG]])<br>
                      +#pragma omp parallel firstprivate(g)<br>
                      +  {<br>
                      +    // LAMBDA: define{{.*}} internal{{.*}} void
                      [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}},
                      %{{.+}}* [[ARG:%.+]])<br>
                      +    // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca
                      i{{[0-9]+}},<br>
                      +    // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}**
                      [[ARG_REF:%.+]],<br>
                      +    // LAMBDA: [[ARG:%.+]] = load %{{.+}}**
                      [[ARG_REF]]<br>
                      +    // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr
                      inbounds %{{.+}}* [[ARG]], i{{[0-9]+}} 0,
                      i{{[0-9]+}} 0<br>
                      +    // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}**
                      [[G_REF_ADDR]]<br>
                      +    // LAMBDA: [[G_VAL:%.+]] = load volatile
                      i{{[0-9]+}}* [[G_REF]]<br>
                      +    // LAMBDA: store volatile i{{[0-9]+}}
                      [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]]<br>
                      +    // LAMBDA: call i32 @__kmpc_cancel_barrier(<br>
                      +    g = 1;<br>
                      +    // LAMBDA: store volatile i{{[0-9]+}} 1,
                      i{{[0-9]+}}* [[G_PRIVATE_ADDR]],<br>
                      +    // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] =
                      getelementptr inbounds %{{.+}}* [[ARG:%.+]],
                      i{{[0-9]+}} 0, i{{[0-9]+}} 0<br>
                      +    // LAMBDA: store i{{[0-9]+}}*
                      [[G_PRIVATE_ADDR]], i{{[0-9]+}}**
                      [[G_PRIVATE_ADDR_REF]]<br>
                      +    // LAMBDA: call void
                      [[<a class="moz-txt-link-abbreviated" href="mailto:INNER_LAMBDA:@.+">INNER_LAMBDA:@.+</a>]](%{{.+}}* [[ARG]])<br>
                      +    [&]() {<br>
                      +      // LAMBDA: define {{.+}} void
                      [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])<br>
                      +      // LAMBDA: store %{{.+}}* [[ARG_PTR]],
                      %{{.+}}** [[ARG_PTR_REF:%.+]],<br>
                      +      g = 2;<br>
                      +      // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}**
                      [[ARG_PTR_REF]]<br>
                      +      // LAMBDA: [[G_PTR_REF:%.+]] =
                      getelementptr inbounds %{{.+}}* [[ARG_PTR]],
                      i{{[0-9]+}} 0, i{{[0-9]+}} 0<br>
                      +      // LAMBDA: [[G_REF:%.+]] = load
                      i{{[0-9]+}}** [[G_PTR_REF]]<br>
                      +      // LAMBDA: store volatile i{{[0-9]+}} 2,
                      i{{[0-9]+}}* [[G_REF]]<br>
                      +    }();<br>
                      +  }<br>
                      +  }();<br>
                      +  return 0;<br>
                      +#elif defined(BLOCKS)<br>
                      +  // BLOCKS: [[<a class="moz-txt-link-abbreviated" href="mailto:G:@.+">G:@.+</a>]] = global i{{[0-9]+}} 1212,<br>
                      +  // BLOCKS-LABEL: @main<br>
                      +  // BLOCKS: call void {{%.+}}(i8*<br>
                      +  ^{<br>
                      +  // BLOCKS: define{{.*}} internal{{.*}} void
                      {{.+}}(i8*<br>
                      +  // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr
                      inbounds %{{.+}}* [[AGG_CAPTURED:%.+]],
                      i{{[0-9]+}} 0, i{{[0-9]+}} 0<br>
                      +  // BLOCKS: store i{{[0-9]+}}* [[G]],
                      i{{[0-9]+}}** [[G_LOCAL_REF]]<br>
                      +  // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}*
                      [[AGG_CAPTURED]] to i8*<br>
                      +  // BLOCKS: call void {{.+}}*
                      @__kmpc_fork_call({{.+}}, i32 1, {{.+}}*
                      [[<a class="moz-txt-link-abbreviated" href="mailto:OMP_REGION:@.+">OMP_REGION:@.+</a>]] to {{.+}}, i8* [[ARG]])<br>
                      +#pragma omp parallel firstprivate(g)<br>
                      +  {<br>
                      +    // BLOCKS: define{{.*}} internal{{.*}} void
                      [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}},
                      %{{.+}}* [[ARG:%.+]])<br>
                      +    // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca
                      i{{[0-9]+}},<br>
                      +    // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}**
                      [[ARG_REF:%.+]],<br>
                      +    // BLOCKS: [[ARG:%.+]] = load %{{.+}}**
                      [[ARG_REF]]<br>
                      +    // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr
                      inbounds %{{.+}}* [[ARG]], i{{[0-9]+}} 0,
                      i{{[0-9]+}} 0<br>
                      +    // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}**
                      [[G_REF_ADDR]]<br>
                      +    // BLOCKS: [[G_VAL:%.+]] = load volatile
                      i{{[0-9]+}}* [[G_REF]]<br>
                      +    // BLOCKS: store volatile i{{[0-9]+}}
                      [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]]<br>
                      +    // BLOCKS: call i32 @__kmpc_cancel_barrier(<br>
                      +    g = 1;<br>
                      +    // BLOCKS: store volatile i{{[0-9]+}} 1,
                      i{{[0-9]+}}* [[G_PRIVATE_ADDR]],<br>
                      +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}<br>
                      +    // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]<br>
                      +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}<br>
                      +    // BLOCKS: call void {{%.+}}(i8*<br>
                      +    ^{<br>
                      +      // BLOCKS: define {{.+}} void {{@.+}}(i8*<br>
                      +      g = 2;<br>
                      +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}<br>
                      +      // BLOCKS: store volatile i{{[0-9]+}} 2,
                      i{{[0-9]+}}*<br>
                      +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}<br>
                      +      // BLOCKS: ret<br>
                      +    }();<br>
                      +  }<br>
                      +  }();<br>
                      +  return 0;<br>
                      +#else<br>
                         S<float> test;<br>
                         int t_var = 0;<br>
                         int vec[] = {1, 2};<br>
                      @@ -58,6 +137,7 @@ int main() {<br>
                           s_arr[0] = var;<br>
                         }<br>
                         return tmain<int>();<br>
                      +#endif<br>
                       }<br>
                      <br>
                       // CHECK: define {{.*}}i{{[0-9]+}} @main()<br>
                      <br>
                      Modified:
                      cfe/trunk/test/OpenMP/parallel_private_codegen.cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_private_codegen.cpp?rev=224323&r1=224322&r2=224323&view=diff"
                        target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_private_codegen.cpp?rev=224323&r1=224322&r2=224323&view=diff</a><br>
==============================================================================<br>
                      ---
                      cfe/trunk/test/OpenMP/parallel_private_codegen.cpp
                      (original)<br>
                      +++
                      cfe/trunk/test/OpenMP/parallel_private_codegen.cpp
                      Tue Dec 16 01:00:22 2014<br>
                      @@ -1,6 +1,8 @@<br>
                       // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x
                      c++ -triple x86_64-unknown-unknown -emit-llvm %s
                      -o - | FileCheck %s<br>
                       // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++
                      -std=c++11 -triple x86_64-unknown-unknown
                      -emit-pch -o %t %s<br>
                       // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++
                      -triple x86_64-unknown-unknown -std=c++11
                      -include-pch %t -verify %s -emit-llvm -o - |
                      FileCheck %s<br>
                      +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x
                      c++ -std=c++11 -DLAMBDA -triple
                      %itanium_abi_triple -emit-llvm %s -o - | FileCheck
                      -check-prefix=LAMBDA %s<br>
                      +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x
                      c++ -fblocks -DBLOCKS -triple %itanium_abi_triple
                      -emit-llvm %s -o - | FileCheck
                      -check-prefix=BLOCKS %s<br>
                       // expected-no-diagnostics<br>
                       #ifndef HEADER<br>
                       #define HEADER<br>
                      @@ -14,6 +16,8 @@ struct S {<br>
                         ~S() {}<br>
                       };<br>
                      <br>
                      +volatile int g = 1212;<br>
                      +<br>
                       // CHECK: [[S_FLOAT_TY:%.+]] = type { float }<br>
                       // CHECK: [[CAP_MAIN_TY:%.+]] = type { [2 x
                      i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x
                      [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* }<br>
                       // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }<br>
                      @@ -22,7 +26,7 @@ struct S {<br>
                       template <typename T><br>
                       T tmain() {<br>
                         S<T> test;<br>
                      -  T t_var;<br>
                      +  T t_var = T();<br>
                         T vec[] = {1, 2};<br>
                         S<T> s_arr[] = {1, 2};<br>
                         S<T> var(3);<br>
                      @@ -35,8 +39,75 @@ T tmain() {<br>
                       }<br>
                      <br>
                       int main() {<br>
                      +#ifdef LAMBDA<br>
                      +  // LAMBDA: [[<a class="moz-txt-link-abbreviated" href="mailto:G:@.+">G:@.+</a>]] = global i{{[0-9]+}} 1212,<br>
                      +  // LAMBDA-LABEL: @main<br>
                      +  // LAMBDA: call void [[<a class="moz-txt-link-abbreviated" href="mailto:OUTER_LAMBDA:@.+">OUTER_LAMBDA:@.+</a>]](<br>
                      +  [&]() {<br>
                      +  // LAMBDA: define{{.*}} internal{{.*}} void
                      [[OUTER_LAMBDA]](<br>
                      +  // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr
                      inbounds %{{.+}}* [[AGG_CAPTURED:%.+]],
                      i{{[0-9]+}} 0, i{{[0-9]+}} 0<br>
                      +  // LAMBDA: store i{{[0-9]+}}* [[G]],
                      i{{[0-9]+}}** [[G_LOCAL_REF]]<br>
                      +  // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}*
                      [[AGG_CAPTURED]] to i8*<br>
                      +  // LAMBDA: call void {{.+}}*
                      @__kmpc_fork_call({{.+}}, i32 1, {{.+}}*
                      [[<a class="moz-txt-link-abbreviated" href="mailto:OMP_REGION:@.+">OMP_REGION:@.+</a>]] to {{.+}}, i8* [[ARG]])<br>
                      +#pragma omp parallel private(g)<br>
                      +  {<br>
                      +    // LAMBDA: define{{.*}} internal{{.*}} void
                      [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}},
                      %{{.+}}* [[ARG:%.+]])<br>
                      +    // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca
                      i{{[0-9]+}},<br>
                      +    // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}**
                      [[ARG_REF:%.+]],<br>
                      +    // LAMBDA: call i32 @__kmpc_cancel_barrier(<br>
                      +    g = 1;<br>
                      +    // LAMBDA: store volatile i{{[0-9]+}} 1,
                      i{{[0-9]+}}* [[G_PRIVATE_ADDR]],<br>
                      +    // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] =
                      getelementptr inbounds %{{.+}}* [[ARG:%.+]],
                      i{{[0-9]+}} 0, i{{[0-9]+}} 0<br>
                      +    // LAMBDA: store i{{[0-9]+}}*
                      [[G_PRIVATE_ADDR]], i{{[0-9]+}}**
                      [[G_PRIVATE_ADDR_REF]]<br>
                      +    // LAMBDA: call void
                      [[<a class="moz-txt-link-abbreviated" href="mailto:INNER_LAMBDA:@.+">INNER_LAMBDA:@.+</a>]](%{{.+}}* [[ARG]])<br>
                      +    [&]() {<br>
                      +      // LAMBDA: define {{.+}} void
                      [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])<br>
                      +      // LAMBDA: store %{{.+}}* [[ARG_PTR]],
                      %{{.+}}** [[ARG_PTR_REF:%.+]],<br>
                      +      g = 2;<br>
                      +      // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}**
                      [[ARG_PTR_REF]]<br>
                      +      // LAMBDA: [[G_PTR_REF:%.+]] =
                      getelementptr inbounds %{{.+}}* [[ARG_PTR]],
                      i{{[0-9]+}} 0, i{{[0-9]+}} 0<br>
                      +      // LAMBDA: [[G_REF:%.+]] = load
                      i{{[0-9]+}}** [[G_PTR_REF]]<br>
                      +      // LAMBDA: store volatile i{{[0-9]+}} 2,
                      i{{[0-9]+}}* [[G_REF]]<br>
                      +    }();<br>
                      +  }<br>
                      +  }();<br>
                      +  return 0;<br>
                      +#elif defined(BLOCKS)<br>
                      +  // BLOCKS: [[<a class="moz-txt-link-abbreviated" href="mailto:G:@.+">G:@.+</a>]] = global i{{[0-9]+}} 1212,<br>
                      +  // BLOCKS-LABEL: @main<br>
                      +  // BLOCKS: call void {{%.+}}(i8*<br>
                      +  ^{<br>
                      +  // BLOCKS: define{{.*}} internal{{.*}} void
                      {{.+}}(i8*<br>
                      +  // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr
                      inbounds %{{.+}}* [[AGG_CAPTURED:%.+]],
                      i{{[0-9]+}} 0, i{{[0-9]+}} 0<br>
                      +  // BLOCKS: store i{{[0-9]+}}* [[G]],
                      i{{[0-9]+}}** [[G_LOCAL_REF]]<br>
                      +  // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}*
                      [[AGG_CAPTURED]] to i8*<br>
                      +  // BLOCKS: call void {{.+}}*
                      @__kmpc_fork_call({{.+}}, i32 1, {{.+}}*
                      [[<a class="moz-txt-link-abbreviated" href="mailto:OMP_REGION:@.+">OMP_REGION:@.+</a>]] to {{.+}}, i8* [[ARG]])<br>
                      +#pragma omp parallel private(g)<br>
                      +  {<br>
                      +    // BLOCKS: define{{.*}} internal{{.*}} void
                      [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}},
                      %{{.+}}* [[ARG:%.+]])<br>
                      +    // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca
                      i{{[0-9]+}},<br>
                      +    // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}**
                      [[ARG_REF:%.+]],<br>
                      +    // BLOCKS: call i32 @__kmpc_cancel_barrier(<br>
                      +    g = 1;<br>
                      +    // BLOCKS: store volatile i{{[0-9]+}} 1,
                      i{{[0-9]+}}* [[G_PRIVATE_ADDR]],<br>
                      +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}<br>
                      +    // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]<br>
                      +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}<br>
                      +    // BLOCKS: call void {{%.+}}(i8*<br>
                      +    ^{<br>
                      +      // BLOCKS: define {{.+}} void {{@.+}}(i8*<br>
                      +      g = 2;<br>
                      +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}<br>
                      +      // BLOCKS: store volatile i{{[0-9]+}} 2,
                      i{{[0-9]+}}*<br>
                      +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}<br>
                      +      // BLOCKS: ret<br>
                      +    }();<br>
                      +  }<br>
                      +  }();<br>
                      +  return 0;<br>
                      +#else<br>
                         S<float> test;<br>
                      -  int t_var;<br>
                      +  int t_var = 0;<br>
                         int vec[] = {1, 2};<br>
                         S<float> s_arr[] = {1, 2};<br>
                         S<float> var(3);<br>
                      @@ -46,6 +117,7 @@ int main() {<br>
                           s_arr[0] = var;<br>
                         }<br>
                         return tmain<int>();<br>
                      +#endif<br>
                       }<br>
                      <br>
                       // CHECK: define i{{[0-9]+}} @main()<br>
                      <br>
                      <br>
                      _______________________________________________<br>
                      cfe-commits mailing list<br>
                      <a moz-do-not-send="true"
                        href="mailto:cfe-commits@cs.uiuc.edu"
                        target="_blank">cfe-commits@cs.uiuc.edu</a><br>
                      <a moz-do-not-send="true"
                        href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits"
                        target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
                    </blockquote>
                  </div>
                  <br>
                </div>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </body>
</html>