[cfe-commits] r147917 - in /cfe/trunk: include/clang/Sema/ScopeInfo.h lib/Driver/ToolChains.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/TreeTransform.h

Eli Friedman eli.friedman at gmail.com
Tue Jan 10 18:36:31 PST 2012


Author: efriedma
Date: Tue Jan 10 20:36:31 2012
New Revision: 147917

URL: http://llvm.org/viewvc/llvm-project?rev=147917&view=rev
Log:
Start refactoring code for capturing variables and 'this' so that it is shared between lambda expressions and block literals.


Modified:
    cfe/trunk/include/clang/Sema/ScopeInfo.h
    cfe/trunk/lib/Driver/ToolChains.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Sema/TreeTransform.h

Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=147917&r1=147916&r2=147917&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Tue Jan 10 20:36:31 2012
@@ -117,8 +117,86 @@
   static bool classof(const FunctionScopeInfo *FSI) { return true; }
 };
 
+class CapturingScopeInfo : public FunctionScopeInfo {
+public:
+  enum ImplicitCaptureStyle {
+    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
+  };
+
+  ImplicitCaptureStyle ImpCaptureStyle;
+
+  class Capture {
+    enum CaptureKind {
+      Cap_This, Cap_ByVal, Cap_ByRef
+    };
+
+    // The variable being captured (if we are not capturing 'this'),
+    // and misc bits descibing the capture.
+    llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
+
+    // Expression to initialize a field of the given type, and whether this
+    // is a nested capture; the expression is only required if we are
+    // capturing ByVal and the variable's type has a non-trivial
+    // copy constructor.
+    llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
+
+  public:
+    Capture(VarDecl *Var, bool isByref, bool isNested, Expr *Cpy)
+      : VarAndKind(Var, isByref ? Cap_ByRef : Cap_ByVal),
+        CopyExprAndNested(Cpy, isNested) {}
+
+    enum IsThisCapture { ThisCapture };
+    Capture(IsThisCapture, bool isNested)
+      : VarAndKind(0, Cap_This),
+        CopyExprAndNested(0, isNested) {
+    }
+
+    bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
+    bool isVariableCapture() const { return !isThisCapture(); }
+    bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByVal; }
+    bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
+    bool isNested() { return CopyExprAndNested.getInt(); }
+
+    VarDecl *getVariable() const {
+      return VarAndKind.getPointer();
+    }
+    Expr *getCopyExpr() const {
+      return CopyExprAndNested.getPointer();
+    }
+  };
+
+  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
+    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0)
+     {}
+
+  /// CaptureMap - A map of captured variables to (index+1) into Captures.
+  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
+
+  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
+  /// zero if 'this' is not captured.
+  unsigned CXXThisCaptureIndex;
+
+  /// Captures - The captures.
+  SmallVector<Capture, 4> Captures;
+
+  void AddCapture(VarDecl *Var, bool isByref, bool isNested, Expr *Cpy) {
+    Captures.push_back(Capture(Var, isByref, isNested, Cpy));
+    CaptureMap[Var] = Captures.size();
+  }
+
+  void AddThisCapture(bool isNested) {
+    Captures.push_back(Capture(Capture::ThisCapture, isNested));
+    CXXThisCaptureIndex = Captures.size();
+  }
+
+  static bool classof(const FunctionScopeInfo *FSI) { 
+    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; 
+  }
+  static bool classof(const CapturingScopeInfo *BSI) { return true; }
+};
+
 /// \brief Retains information about a block that is currently being parsed.
-class BlockScopeInfo : public FunctionScopeInfo {
+class BlockScopeInfo : public CapturingScopeInfo {
 public:
   BlockDecl *TheDecl;
   
@@ -134,18 +212,9 @@
   /// Its return type may be BuiltinType::Dependent.
   QualType FunctionType;
 
-  /// CaptureMap - A map of captured variables to (index+1) into Captures.
-  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
-
-  /// Captures - The captured variables.
-  SmallVector<BlockDecl::Capture, 4> Captures;
-
-  /// CapturesCXXThis - Whether this block captures 'this'.
-  bool CapturesCXXThis;
-
   BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
-    : FunctionScopeInfo(Diag), TheDecl(Block), TheScope(BlockScope),
-      CapturesCXXThis(false)
+    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
+      TheScope(BlockScope)
   {
     Kind = SK_Block;
   }
@@ -158,70 +227,30 @@
   static bool classof(const BlockScopeInfo *BSI) { return true; }
 };
 
-class LambdaScopeInfo : public FunctionScopeInfo {
+class LambdaScopeInfo : public CapturingScopeInfo {
 public:
-
-  class Capture {
-    llvm::PointerIntPair<VarDecl*, 2, LambdaCaptureKind> InitAndKind;
-
-  public:
-    Capture(VarDecl *Var, LambdaCaptureKind Kind)
-      : InitAndKind(Var, Kind) {}
-
-    enum IsThisCapture { ThisCapture };
-    Capture(IsThisCapture)
-      : InitAndKind(0, LCK_This) {}
-
-    bool isThisCapture() const { return InitAndKind.getInt() == LCK_This; }
-    bool isVariableCapture() const { return !isThisCapture(); }
-    bool isCopyCapture() const { return InitAndKind.getInt() == LCK_ByCopy; }
-    bool isReferenceCapture() const { return InitAndKind.getInt() == LCK_ByRef; }
-
-    VarDecl *getVariable() const {
-      return InitAndKind.getPointer();
-    }
-
-  };
-
   /// \brief The class that describes the lambda.
   CXXRecordDecl *Lambda;
   
-  /// \brief A mapping from the set of captured variables to the 
-  /// fields (within the lambda class) that represent the captured variables.
-  llvm::DenseMap<VarDecl *, FieldDecl *> CapturedVariables;
-
-  /// \brief The list of captured variables, starting with the explicit 
-  /// captures and then finishing with any implicit captures.
-  llvm::SmallVector<Capture, 4> Captures;
-
-  // \brief Whether we have already captured 'this'.
-  bool CapturesCXXThis;
-
   /// \brief The number of captures in the \c Captures list that are 
   /// explicit captures.
   unsigned NumExplicitCaptures;
 
-  LambdaCaptureDefault Default;
-
-  /// \brief The field associated with the captured 'this' pointer.
-  FieldDecl *ThisCapture;
-
   /// \brief - Whether the return type of the lambda is implicit
   bool HasImplicitReturnType;
 
   /// ReturnType - The return type of the lambda, or null if unknown.
   QualType ReturnType;
 
-  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda) 
-    : FunctionScopeInfo(Diag), Lambda(Lambda), CapturesCXXThis(false),
-      NumExplicitCaptures(0), Default(LCD_None), ThisCapture(0),
-      HasImplicitReturnType(false)
+  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda)
+    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
+      NumExplicitCaptures(0), HasImplicitReturnType(false)
   {
     Kind = SK_Lambda;
   }
-    
+
   virtual ~LambdaScopeInfo();
-  
+
   static bool classof(const FunctionScopeInfo *FSI) { 
     return FSI->Kind == SK_Lambda; 
   }

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=147917&r1=147916&r2=147917&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Tue Jan 10 20:36:31 2012
@@ -533,24 +533,15 @@
   Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
   Arg *iOSSimVersion = Args.getLastArg(
     options::OPT_mios_simulator_version_min_EQ);
-
-  // FIXME: HACK! When compiling for the simulator we don't get a
-  // '-miphoneos-version-min' to help us know whether there is an ARC runtime
-  // or not; try to parse a __IPHONE_OS_VERSION_MIN_REQUIRED
-  // define passed in command-line.
-  if (!iOSVersion && !iOSSimVersion) {
+ 
+  if (!iOSSimVersion) {
+    // As a legacy hack, treat -D__IPHONE_OS_VERSION_MIN_REQUIRED=40201 as
+    // equivalent to -mios-simulator-version-min.
     for (arg_iterator it = Args.filtered_begin(options::OPT_D),
            ie = Args.filtered_end(); it != ie; ++it) {
       StringRef define = (*it)->getValue(Args);
       if (define.startswith(SimulatorVersionDefineName())) {
-        unsigned Major = 0, Minor = 0, Micro = 0;
-        if (GetVersionFromSimulatorDefine(define, Major, Minor, Micro) &&
-            Major < 10 && Minor < 100 && Micro < 100) {
-          ARCRuntimeForSimulator = Major < 5 ? ARCSimulator_NoARCRuntime
-                                             : ARCSimulator_HasARCRuntime;
-          LibCXXForSimulator = Major < 5 ? LibCXXSimulator_NotAvailable
-                                         : LibCXXSimulator_Available;
-        }
+        iOSSimVersion = *it;
         break;
       }
     }
@@ -661,11 +652,21 @@
   } else {
     const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion;
     assert(Version && "Unknown target platform!");
-    if (!Driver::GetReleaseVersion(Version->getValue(Args), Major, Minor,
-                                   Micro, HadExtra) || HadExtra ||
-        Major >= 10 || Minor >= 100 || Micro >= 100)
-      getDriver().Diag(diag::err_drv_invalid_version_number)
-        << Version->getAsString(Args);
+    if (Version->getOption().getID() == options::OPT_D) {
+      // If the simulator version comes from a define, parse that.
+      if (!GetVersionFromSimulatorDefine(Version->getValue(Args), Major,
+                                         Minor, Micro) ||
+          Major >= 10 || Minor >= 100 || Micro >= 100)
+        getDriver().Diag(diag::err_drv_invalid_version_number)
+          << Version->getAsString(Args);
+    } else {
+      // Otherwise, use the normal version parsing code.
+      if (!Driver::GetReleaseVersion(Version->getValue(Args), Major, Minor,
+                                     Micro, HadExtra) ||
+          HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100)
+        getDriver().Diag(diag::err_drv_invalid_version_number)
+          << Version->getAsString(Args);
+    }
   }
 
   bool IsIOSSim = bool(iOSSimVersion);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=147917&r1=147916&r2=147917&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 10 20:36:31 2012
@@ -1248,20 +1248,16 @@
 /// There is a well-formed capture at a particular scope level;
 /// propagate it through all the nested blocks.
 static CaptureResult propagateCapture(Sema &S, unsigned ValidScopeIndex,
-                                      const BlockDecl::Capture &Capture) {
-  VarDecl *var = Capture.getVariable();
-
+                                      const CapturingScopeInfo::Capture &Cap) {
   // Update all the inner blocks with the capture information.
   for (unsigned i = ValidScopeIndex + 1, e = S.FunctionScopes.size();
          i != e; ++i) {
     BlockScopeInfo *innerBlock = cast<BlockScopeInfo>(S.FunctionScopes[i]);
-    innerBlock->Captures.push_back(
-      BlockDecl::Capture(Capture.getVariable(), Capture.isByRef(),
-                         /*nested*/ true, Capture.getCopyExpr()));
-    innerBlock->CaptureMap[var] = innerBlock->Captures.size(); // +1
+    innerBlock->AddCapture(Cap.getVariable(), Cap.isReferenceCapture(),
+                           /*nested*/ true, Cap.getCopyExpr());
   }
 
-  return Capture.isByRef() ? CR_CaptureByRef : CR_Capture;
+  return Cap.isReferenceCapture() ? CR_CaptureByRef : CR_Capture;
 }
 
 /// shouldCaptureValueReference - Determine if a reference to the
@@ -1372,9 +1368,7 @@
     cast<BlockScopeInfo>(S.FunctionScopes[functionScopesIndex]);
 
   // Build a valid capture in this scope.
-  blockScope->Captures.push_back(
-                 BlockDecl::Capture(var, byRef, /*nested*/ false, copyExpr));
-  blockScope->CaptureMap[var] = blockScope->Captures.size(); // +1
+  blockScope->AddCapture(var, byRef, /*nested*/ false, copyExpr);
 
   // Propagate that to inner captures if necessary.
   return propagateCapture(S, functionScopesIndex,
@@ -8861,8 +8855,18 @@
   QualType BlockTy;
 
   // Set the captured variables on the block.
-  BSI->TheDecl->setCaptures(Context, BSI->Captures.begin(), BSI->Captures.end(),
-                            BSI->CapturesCXXThis);
+  // FIXME: Share capture structure between BlockDecl and CapturingScopeInfo!
+  SmallVector<BlockDecl::Capture, 4> Captures;
+  for (unsigned i = 0, e = BSI->Captures.size(); i != e; i++) {
+    CapturingScopeInfo::Capture &Cap = BSI->Captures[i];
+    if (Cap.isThisCapture())
+      continue;
+    BlockDecl::Capture NewCap(Cap.getVariable(), Cap.isReferenceCapture(),
+                              Cap.isNested(), Cap.getCopyExpr());
+    Captures.push_back(NewCap);
+  }
+  BSI->TheDecl->setCaptures(Context, Captures.begin(), Captures.end(),
+                            BSI->CXXThisCaptureIndex != 0);
 
   // If the user wrote a function type in some form, try to use that.
   if (!BSI->FunctionType.isNull()) {

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=147917&r1=147916&r2=147917&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Jan 10 20:36:31 2012
@@ -680,19 +680,21 @@
   // Otherwise, check that we can capture 'this'.
   unsigned NumClosures = 0;
   for (unsigned idx = FunctionScopes.size() - 1; idx != 0; idx--) {
-    if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(FunctionScopes[idx])) {
-      if (LSI->CapturesCXXThis) {
-        // This lambda already captures 'this'; there isn't anything more to do.
+    if (CapturingScopeInfo *CSI =
+            dyn_cast<CapturingScopeInfo>(FunctionScopes[idx])) {
+      if (CSI->CXXThisCaptureIndex != 0) {
+        // 'this' is already being captured; there isn't anything more to do.
         break;
       }
-      if (LSI->Default == LCD_ByRef) {
-        // This lambda can implicitly capture 'this'; continue looking upwards.
+      if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref ||
+          CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block) {
+        // This closure can implicitly capture 'this'; continue looking upwards.
         // FIXME: Is this check correct?  The rules in the standard are a bit
         // unclear.
         NumClosures++;
         continue;
       }
-      // This lambda can't implicitly capture 'this'; fail out.
+      // This context can't implicitly capture 'this'; fail out.
       // (We need to delay the diagnostic in the
       // PotentiallyPotentiallyEvaluated case because it doesn't apply to
       // unevaluated contexts.)
@@ -703,10 +705,6 @@
         Diag(Loc, diag::err_implicit_this_capture);
       return;
     }
-    if (isa<BlockScopeInfo>(FunctionScopes[idx])) {
-      NumClosures++;
-      continue;
-    }
     break;
   }
 
@@ -715,14 +713,9 @@
   // contexts.
   for (unsigned idx = FunctionScopes.size() - 1;
        NumClosures; --idx, --NumClosures) {
-    if (BlockScopeInfo *BSI = dyn_cast<BlockScopeInfo>(FunctionScopes[idx])) {
-      BSI->CapturesCXXThis = true;
-    } else {
-      LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(FunctionScopes[idx]);
-      assert(LSI && "Unexpected closure");
-      LSI->CapturesCXXThis = true;
-      LSI->Captures.push_back(LambdaScopeInfo::Capture::ThisCapture);
-    }
+    CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
+    bool isNested = NumClosures > 1;
+    CSI->AddThisCapture(isNested);
   }
 }
 
@@ -4831,8 +4824,9 @@
   CurContext->addDecl(Class);
 
   QualType ThisCaptureType;
+  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
+  unsigned CXXThisCaptureIndex = 0;
   llvm::SmallVector<LambdaScopeInfo::Capture, 4> Captures;
-  llvm::DenseMap<const IdentifierInfo*, SourceLocation> CapturesSoFar;
   for (llvm::SmallVector<LambdaCapture, 4>::const_iterator
        C = Intro.Captures.begin(), E = Intro.Captures.end(); C != E; ++C) {
     if (C->Kind == LCK_This) {
@@ -4853,7 +4847,12 @@
       }
       CheckCXXThisCapture(C->Loc);
 
-      Captures.push_back(LambdaScopeInfo::Capture::ThisCapture);
+      // FIXME: Need getCurCapture().
+      bool isNested = getCurBlock() || getCurLambda();
+      CapturingScopeInfo::Capture Cap(CapturingScopeInfo::Capture::ThisCapture,
+                                      isNested);
+      Captures.push_back(Cap);
+      CXXThisCaptureIndex = Captures.size();
       continue;
     }
 
@@ -4867,16 +4866,6 @@
       continue;
     }
 
-    llvm::DenseMap<const IdentifierInfo*, SourceLocation>::iterator Appearance;
-    bool IsFirstAppearance;
-    llvm::tie(Appearance, IsFirstAppearance)
-      = CapturesSoFar.insert(std::make_pair(C->Id, C->Loc));
-
-    if (!IsFirstAppearance) {
-      Diag(C->Loc, diag::err_capture_more_than_once) << C->Id;
-      continue;
-    }
-
     DeclarationNameInfo Name(C->Id, C->Loc);
     LookupResult R(*this, Name, LookupOrdinaryName);
     CXXScopeSpec ScopeSpec;
@@ -4893,16 +4882,22 @@
       continue;
     }
 
+    if (CaptureMap.count(Var)) {
+      Diag(C->Loc, diag::err_capture_more_than_once) << C->Id;
+      continue;
+    }
+
     if (!Var->hasLocalStorage()) {
       Diag(C->Loc, diag::err_capture_non_automatic_variable) << C->Id;
       continue;
     }
 
-    // FIXME: Actually capturing a variable is much more complicated than this
-    // in the general case; see shouldCaptureValueReference.
-    // FIXME: Should we be building a DeclRefExpr here?  We don't really need
-    // it until the point where we're actually building the LambdaExpr.
-    Captures.push_back(LambdaScopeInfo::Capture(Var, C->Kind));
+    // FIXME: This is completely wrong for nested captures and variables
+    // with a non-trivial constructor.
+    // FIXME: We should refuse to capture __block variables.
+    Captures.push_back(LambdaScopeInfo::Capture(Var, C->Kind == LCK_ByRef,
+                                                /*isNested*/false, 0));
+    CaptureMap[Var] = Captures.size();
   }
 
   // Build the call operator; we don't really have all the relevant information
@@ -4982,15 +4977,20 @@
   PushLambdaScope(Class);
 
   LambdaScopeInfo *LSI = getCurLambda();
-  LSI->Default = Intro.Default;
-  if (!ThisCaptureType.isNull())
-    LSI->CapturesCXXThis = true;
+  LSI->CXXThisCaptureIndex = CXXThisCaptureIndex;
+  std::swap(LSI->CaptureMap, CaptureMap);
   std::swap(LSI->Captures, Captures);
+  LSI->NumExplicitCaptures = Captures.size();
+  if (Intro.Default == LCD_ByCopy)
+    LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
+  else if (Intro.Default == LCD_ByRef)
+    LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref;
 
   const FunctionType *Fn = MethodTy->getAs<FunctionType>();
   QualType RetTy = Fn->getResultType();
   if (RetTy != Context.DependentTy) {
     LSI->ReturnType = RetTy;
+  } else {
     LSI->HasImplicitReturnType = true;
   }
 

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=147917&r1=147916&r2=147917&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Jan 10 20:36:31 2012
@@ -265,8 +265,7 @@
     if (captureIndex) break;
 
     bool nested = isa<BlockScopeInfo>(FunctionScopes[idx-1]);
-    blockScope->Captures.push_back(
-              BlockDecl::Capture(self, /*byref*/ false, nested, /*copy*/ 0));
+    blockScope->AddCapture(self, /*byref*/ false, nested, /*copy*/ 0);
     captureIndex = blockScope->Captures.size(); // +1
   }
 

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=147917&r1=147916&r2=147917&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Jan 10 20:36:31 2012
@@ -1890,6 +1890,7 @@
   ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
                                 QualType ThisType,
                                 bool isImplicit) {
+    getSema().CheckCXXThisCapture(ThisLoc);
     return getSema().Owned(
                       new (getSema().Context) CXXThisExpr(ThisLoc, ThisType,
                                                           isImplicit));
@@ -8114,10 +8115,6 @@
   BlockScopeInfo *blockScope = SemaRef.getCurBlock();
 
   blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
-  // We built a new blockScopeInfo in call to ActOnBlockStart
-  // in above, CapturesCXXThis need be set here from the block
-  // expression.
-  blockScope->CapturesCXXThis = oldBlock->capturesCXXThis();
   blockScope->TheDecl->setBlockMissingReturnType(
                          oldBlock->blockMissingReturnType());
   





More information about the cfe-commits mailing list