[cfe-commits] r147723 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/ScopeInfo.h include/clang/Sema/Sema.h lib/AST/DeclCXX.cpp lib/Sema/Sema.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaExprMember.cpp lib/Sema/SemaOverload.cpp test/Parser/objcxx0x-lambda-expressions.mm test/SemaCXX/lambda-expressions.cpp

Eli Friedman eli.friedman at gmail.com
Fri Jan 6 20:59:52 PST 2012


Author: efriedma
Date: Fri Jan  6 22:59:52 2012
New Revision: 147723

URL: http://llvm.org/viewvc/llvm-project?rev=147723&view=rev
Log:
More lambda work: semantic analysis of capturing 'this'.  It's a bit complicated, but we have to be careful about when exactly captures are marked given PotentiallyPotentiallyEvaluated contexts.  (Actually, it's not 100% correct yet, but it's close enough for the moment.)


Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/ScopeInfo.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprMember.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm
    cfe/trunk/test/SemaCXX/lambda-expressions.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Jan  6 22:59:52 2012
@@ -500,6 +500,9 @@
     /// declared but would have been deleted.
     bool FailedImplicitMoveAssignment : 1;
 
+    /// \brief Whether this class describes a C++ lambda.
+    bool IsLambda : 1;
+
     /// NumBases - The number of base class specifiers in Bases.
     unsigned NumBases;
 
@@ -908,6 +911,11 @@
   /// This value is used for lazy creation of destructors.
   bool hasDeclaredDestructor() const { return data().DeclaredDestructor; }
 
+  /// \brief Determine whether this class describes a lambda function object.
+  bool isLambda() const { return data().IsLambda; }
+  
+  void setLambda(bool Lambda = true) { data().IsLambda = Lambda; }
+
   /// getConversions - Retrieve the overload set containing all of the
   /// conversion functions in this class.
   UnresolvedSetImpl *getConversionFunctions() {

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan  6 22:59:52 2012
@@ -4004,6 +4004,8 @@
   "%0 in capture list does not name a variable">;
 def err_capture_non_automatic_variable : Error<
   "%0 cannot be captured because it does not have automatic storage duration">;
+def err_implicit_this_capture : Error<
+  "'this' cannot be implicitly captured in this context">;
 
 def err_operator_arrow_circular : Error<
   "circular pointer delegation detected">;

Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Fri Jan  6 22:59:52 2012
@@ -189,15 +189,20 @@
   /// \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;
 
@@ -208,8 +213,9 @@
   QualType ReturnType;
 
   LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda) 
-    : FunctionScopeInfo(Diag), Lambda(Lambda), 
-      NumExplicitCaptures(0), ThisCapture(0) , HasImplicitReturnType(false)
+    : FunctionScopeInfo(Diag), Lambda(Lambda), CapturesCXXThis(false),
+      NumExplicitCaptures(0), Default(LCD_None), ThisCapture(0),
+      HasImplicitReturnType(false)
   {
     Kind = SK_Lambda;
   }

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jan  6 22:59:52 2012
@@ -3099,7 +3099,12 @@
   /// \param Capture If true, capture 'this' in this context.
   ///
   /// \returns The type of 'this', if possible. Otherwise, returns a NULL type.
-  QualType getCurrentThisType(bool Capture = true);
+  QualType getCurrentThisType();
+
+  /// \brief Make sure the value of 'this' is actually available in the current
+  /// context, if it is a potentially evaluated context. This check can be
+  /// delayed in PotentiallyPotentiallyEvaluated contexts.
+  void CheckCXXThisCapture(SourceLocation Loc);
 
   /// ActOnCXXBoolLiteral - Parse {true,false} literals.
   ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Fri Jan  6 22:59:52 2012
@@ -57,8 +57,8 @@
     DeclaredCopyConstructor(false), DeclaredMoveConstructor(false),
     DeclaredCopyAssignment(false), DeclaredMoveAssignment(false),
     DeclaredDestructor(false), FailedImplicitMoveConstructor(false),
-    FailedImplicitMoveAssignment(false), NumBases(0), NumVBases(0), Bases(),
-    VBases(), Definition(D), FirstFriend(0) {
+    FailedImplicitMoveAssignment(false), IsLambda(false), NumBases(0),
+    NumVBases(0), Bases(), VBases(), Definition(D), FirstFriend(0) {
 }
 
 CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Fri Jan  6 22:59:52 2012
@@ -636,8 +636,16 @@
 DeclContext *Sema::getFunctionLevelDeclContext() {
   DeclContext *DC = CurContext;
 
-  while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
-    DC = DC->getParent();
+  while (true) {
+    if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC)) {
+      DC = DC->getParent();
+    } else if (isa<CXXMethodDecl>(DC) &&
+               cast<CXXRecordDecl>(DC->getParent())->hasDefinition() &&
+               cast<CXXRecordDecl>(DC->getParent())->isLambda()) {
+      DC = DC->getParent()->getParent();
+    }
+    else break;
+  }
 
   return DC;
 }

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Fri Jan  6 22:59:52 2012
@@ -1751,7 +1751,7 @@
   case Sema::PCC_Expression: {
     if (SemaRef.getLangOptions().CPlusPlus) {
       // 'this', if we're in a non-static member function.
-      QualType ThisTy = SemaRef.getCurrentThisType(false);
+      QualType ThisTy = SemaRef.getCurrentThisType();
       if (!ThisTy.isNull()) {
         Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy, 
                                                            SemaRef.Context, 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jan  6 22:59:52 2012
@@ -1544,6 +1544,7 @@
             Diag(R.getNameLoc(), diagnostic) << Name
               << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
             QualType DepThisType = DepMethod->getThisType(Context);
+            CheckCXXThisCapture(R.getNameLoc());
             CXXThisExpr *DepThis = new (Context) CXXThisExpr(
                                        R.getNameLoc(), DepThisType, false);
             TemplateArgumentListInfo TList;

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Jan  6 22:59:52 2012
@@ -653,22 +653,8 @@
   return Owned(E);
 }
 
-QualType Sema::getCurrentThisType(bool Capture) {
-  // Ignore block scopes: we can capture through them.
-  // Ignore nested enum scopes: we'll diagnose non-constant expressions
-  // where they're invalid, and other uses are legitimate.
-  // Don't ignore nested class scopes: you can't use 'this' in a local class.
-  DeclContext *DC = CurContext;
-  unsigned NumBlocks = 0;
-  while (true) {
-    if (isa<BlockDecl>(DC)) {
-      DC = cast<BlockDecl>(DC)->getDeclContext();
-      ++NumBlocks;
-    } else if (isa<EnumDecl>(DC))
-      DC = cast<EnumDecl>(DC)->getDeclContext();
-    else break;
-  }
-
+QualType Sema::getCurrentThisType() {
+  DeclContext *DC = getFunctionLevelDeclContext();
   QualType ThisTy;
   if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) {
     if (method && method->isInstance())
@@ -683,17 +669,63 @@
       ThisTy = Context.getPointerType(Context.getRecordType(RD));
   }
 
-  if (!Capture || ThisTy.isNull())
-    return ThisTy;
-  
-  // Mark that we're closing on 'this' in all the block scopes we ignored.
-  for (unsigned idx = FunctionScopes.size() - 1;
-       NumBlocks; --idx, --NumBlocks)
-    cast<BlockScopeInfo>(FunctionScopes[idx])->CapturesCXXThis = true;
-
   return ThisTy;
 }
 
+void Sema::CheckCXXThisCapture(SourceLocation Loc) {
+  // We don't need to capture this in an unevaluated context.
+  if (ExprEvalContexts.back().Context == Unevaluated)
+    return;
+
+  // 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.
+        break;
+      }
+      if (LSI->Default == LCD_ByRef) {
+        // This lambda 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.
+      // (We need to delay the diagnostic in the
+      // PotentiallyPotentiallyEvaluated case because it doesn't apply to
+      // unevaluated contexts.)
+      if (ExprEvalContexts.back().Context == PotentiallyPotentiallyEvaluated)
+        ExprEvalContexts.back()
+            .addDiagnostic(Loc, PDiag(diag::err_implicit_this_capture));
+      else
+        Diag(Loc, diag::err_implicit_this_capture);
+      return;
+    }
+    if (isa<BlockScopeInfo>(FunctionScopes[idx])) {
+      NumClosures++;
+      continue;
+    }
+    break;
+  }
+
+  // Mark that we're implicitly capturing 'this' in all the scopes we skipped.
+  // FIXME: We need to delay this marking in PotentiallyPotentiallyEvaluated
+  // 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);
+    }
+  }
+}
+
 ExprResult Sema::ActOnCXXThis(SourceLocation Loc) {
   /// C++ 9.3.2: In the body of a non-static member function, the keyword this
   /// is a non-lvalue expression whose value is the address of the object for
@@ -702,6 +734,7 @@
   QualType ThisTy = getCurrentThisType();
   if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use);
 
+  CheckCXXThisCapture(Loc);
   return Owned(new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false));
 }
 
@@ -4791,14 +4824,11 @@
                                                /*IdLoc=*/SourceLocation(),
                                                /*Id=*/0);
   Class->startDefinition();
+  Class->setLambda(true);
   CurContext->addDecl(Class);
 
-  // Introduce the lambda scope.
-  PushLambdaScope(Class);
-
-  LambdaScopeInfo *LSI = getCurLambda();
-
   QualType ThisCaptureType;
+  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) {
@@ -4814,12 +4844,13 @@
       }
 
       ThisCaptureType = getCurrentThisType();
-
       if (ThisCaptureType.isNull()) {
         Diag(C->Loc, diag::err_invalid_this_use);
         continue;
       }
-      LSI->Captures.push_back(LambdaScopeInfo::Capture::ThisCapture);
+      CheckCXXThisCapture(C->Loc);
+
+      Captures.push_back(LambdaScopeInfo::Capture::ThisCapture);
       continue;
     }
 
@@ -4868,7 +4899,7 @@
     // 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.
-    LSI->Captures.push_back(LambdaScopeInfo::Capture(Var, C->Kind));
+    Captures.push_back(LambdaScopeInfo::Capture(Var, C->Kind));
   }
 
   // Build the call operator; we don't really have all the relevant information
@@ -4944,6 +4975,15 @@
     }
   }
 
+  // Introduce the lambda scope.
+  PushLambdaScope(Class);
+
+  LambdaScopeInfo *LSI = getCurLambda();
+  LSI->Default = Intro.Default;
+  if (!ThisCaptureType.isNull())
+    LSI->CapturesCXXThis = true;
+  std::swap(LSI->Captures, Captures);
+
   const FunctionType *Fn = MethodTy->getAs<FunctionType>();
   QualType RetTy = Fn->getResultType();
   if (RetTy != Context.DependentTy) {

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Fri Jan  6 22:59:52 2012
@@ -705,6 +705,7 @@
     }
     
     // Our base object expression is "this".
+    CheckCXXThisCapture(loc);
     baseObjectExpr 
       = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/ true);
     baseObjectIsPointer = true;
@@ -854,6 +855,7 @@
     SourceLocation Loc = R.getNameLoc();
     if (SS.getRange().isValid())
       Loc = SS.getRange().getBegin();
+    CheckCXXThisCapture(Loc);
     BaseExpr = new (Context) CXXThisExpr(Loc, BaseExprType,/*isImplicit=*/true);
   }
 
@@ -1556,6 +1558,7 @@
     SourceLocation Loc = R.getNameLoc();
     if (SS.getRange().isValid())
       Loc = SS.getRange().getBegin();
+    CheckCXXThisCapture(Loc);
     baseExpr = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/true);
   }
   

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Jan  6 22:59:52 2012
@@ -10401,6 +10401,7 @@
         SourceLocation Loc = MemExpr->getMemberLoc();
         if (MemExpr->getQualifier())
           Loc = MemExpr->getQualifierLoc().getBeginLoc();
+        CheckCXXThisCapture(Loc);
         Base = new (Context) CXXThisExpr(Loc,
                                          MemExpr->getBaseType(),
                                          /*isImplicit=*/true);

Modified: cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm (original)
+++ cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm Fri Jan  6 22:59:52 2012
@@ -14,7 +14,8 @@
     [] {}; // expected-error {{lambda expressions are not supported yet}}
     [=] (int i) {}; // expected-error {{lambda expressions are not supported yet}}
     [&] (int) mutable -> void {}; // expected-error {{lambda expressions are not supported yet}}
-    [foo,bar] () { return 3; }; // expected-error {{lambda expressions are not supported yet}}
+    // FIXME: Implicit return type deduction doesn't work yet.
+    [foo,bar] () { return 3; }; // expected-error {{void function 'f' should not return a value}} expected-error {{lambda expressions are not supported yet}}
     [=,&foo] () {}; // expected-error {{lambda expressions are not supported yet}}
     [this] () {}; // expected-error {{lambda expressions are not supported yet}}
   }

Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=147723&r1=147722&r2=147723&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original)
+++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Fri Jan  6 22:59:52 2012
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
 
+namespace std { class type_info; };
+
 namespace ExplicitCapture {
   int GlobalVar; // expected-note {{declared here}}
 
@@ -10,10 +12,13 @@
   using namespace N;
 
   class C {
-    int x;
+    int Member;
+
+    static void Overload(int);
+    void Overload();
+    virtual C& Overload(float);
 
-    void f(int);
-    void f() {
+    void ExplicitCapture() {
       int foo;
 
       [foo, foo] () {}; // expected-error {{'foo' can appear only once}} expected-error {{not supported yet}}
@@ -24,11 +29,23 @@
       [&, foo] () {}; // expected-error {{not supported yet}}
       [&, &foo] () {}; // expected-error {{'&' cannot precede a capture when}} expected-error {{not supported yet}}
       [&, this] () {}; // expected-error {{not supported yet}}
-      [&f] () {}; // expected-error {{does not name a variable}} expected-error {{not supported yet}}
+      [&Overload] () {}; // expected-error {{does not name a variable}} expected-error {{not supported yet}}
       [&GlobalVar] () {}; // expected-error {{does not have automatic storage duration}} expected-error {{not supported yet}}
       [&AmbiguousVar] () {} // expected-error {{reference to 'AmbiguousVar' is ambiguous}} expected-error {{not supported yet}}
       [&Globalvar] () {}; // expected-error {{use of undeclared identifier 'Globalvar'; did you mean 'GlobalVar}}
     }
+
+    void ImplicitThisCapture() {
+      [](){(void)Member;}; // expected-error {{'this' cannot be implicitly captured in this context}} expected-error {{not supported yet}}
+      [&](){(void)Member;}; // expected-error {{not supported yet}}
+      [this](){(void)Member;}; // expected-error {{not supported yet}}
+      [this]{[this]{};};// expected-error 2 {{not supported yet}}
+      []{[this]{};};// expected-error {{'this' cannot be implicitly captured in this context}} expected-error 2 {{not supported yet}}
+      []{Overload(3);}; // expected-error {{not supported yet}}
+      []{Overload();}; // expected-error {{'this' cannot be implicitly captured in this context}} expected-error {{not supported yet}}
+      []{(void)typeid(Overload());};// expected-error {{not supported yet}}
+      []{(void)typeid(Overload(.5f));};// expected-error {{'this' cannot be implicitly captured in this context}} expected-error {{not supported yet}}
+    }
   };
 
   void f() {





More information about the cfe-commits mailing list