[cfe-commits] r150087 - in /cfe/trunk: include/clang/AST/ExprCXX.h include/clang/Sema/ScopeInfo.h include/clang/Sema/Sema.h lib/Sema/Sema.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp

Douglas Gregor dgregor at apple.com
Wed Feb 8 12:17:15 PST 2012


Author: dgregor
Date: Wed Feb  8 14:17:14 2012
New Revision: 150087

URL: http://llvm.org/viewvc/llvm-project?rev=150087&view=rev
Log:
When completing a lambda expression, make sure to check and attach the
body of the lambda to the function call operator.

Added:
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp   (with props)
Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/Sema/ScopeInfo.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Feb  8 14:17:14 2012
@@ -1226,8 +1226,7 @@
   }
 
   /// \brief Retrieve the iterator pointing one past the last
-  /// initialization argument for this lambda expression (which
-  /// initializes the first capture field).
+  /// initialization argument for this lambda expression.
   capture_init_iterator capture_init_end() const {
     return capture_init_begin() + NumCaptures;
   }

Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Wed Feb  8 14:17:14 2012
@@ -280,6 +280,9 @@
   /// \brief The class that describes the lambda.
   CXXRecordDecl *Lambda;
 
+  /// \brief The class that describes the lambda.
+  CXXMethodDecl *CallOperator;
+
   /// \brief Source range covering the lambda introducer [...].
   SourceRange IntroducerRange;
 
@@ -292,9 +295,10 @@
   /// \brief Whether the (empty) parameter list is explicit.
   bool ExplicitParams;
 
-  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda)
+  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
+                  CXXMethodDecl *CallOperator)
     : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
-      NumExplicitCaptures(0), Mutable(false)
+      CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(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=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Feb  8 14:17:14 2012
@@ -732,7 +732,7 @@
 
   void PushFunctionScope();
   void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
-  void PushLambdaScope(CXXRecordDecl *Lambda);
+  void PushLambdaScope(CXXRecordDecl *Lambda, CXXMethodDecl *CallOperator);
   void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP =0,
                             const Decl *D = 0, const BlockExpr *blkExpr = 0);
 

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Wed Feb  8 14:17:14 2012
@@ -831,8 +831,10 @@
                                               BlockScope, Block));
 }
 
-void Sema::PushLambdaScope(CXXRecordDecl *Lambda) {
-  FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda));
+void Sema::PushLambdaScope(CXXRecordDecl *Lambda, 
+                           CXXMethodDecl *CallOperator) {
+  FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda,
+                                               CallOperator));
 }
 
 void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Feb  8 14:17:14 2012
@@ -7236,7 +7236,8 @@
       computeNRVO(Body, getCurFunction());
     }
     
-    assert(FD == getCurFunctionDecl() && "Function parsing confused");
+    assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) &&
+           "Function parsing confused");
   } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
     assert(MD == getCurMethodDecl() && "Method parsing confused");
     MD->setBody(Body);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Feb  8 14:17:14 2012
@@ -9722,8 +9722,6 @@
       // of the copy/move done to move a __block variable to the heap.
       type.addConst();
 
-      // FIXME: Add an initialized entity for lambda capture.
-      // FIXME: Won't work for arrays, although we do need this behavior.
       Expr *declRef = new (Context) DeclRefExpr(var, type, VK_LValue, loc);
       ExprResult result =
         PerformCopyInitialization(

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Feb  8 14:17:14 2012
@@ -4896,6 +4896,7 @@
   QualType MethodTy;
   TypeSourceInfo *MethodTyInfo;
   bool ExplicitParams = true;
+  SourceLocation EndLoc;
   if (ParamInfo.getNumTypeObjects() == 0) {
     // C++11 [expr.prim.lambda]p4:
     //   If a lambda-expression does not include a lambda-declarator, it is as 
@@ -4906,6 +4907,7 @@
                                        /*Args=*/0, /*NumArgs=*/0, EPI);
     MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
     ExplicitParams = false;
+    EndLoc = Intro.Range.getEnd();
   } else {
     assert(ParamInfo.isFunctionDeclarator() &&
            "lambda-declarator is a function");
@@ -4928,6 +4930,7 @@
     assert(MethodTyInfo && "no type from lambda-declarator");
     MethodTy = MethodTyInfo->getType();
     assert(!MethodTy.isNull() && "no type from lambda declarator");
+    EndLoc = ParamInfo.getSourceRange().getEnd();
   }
   
   // C++11 [expr.prim.lambda]p5:
@@ -4937,19 +4940,22 @@
   //   trailing-return-type respectively.
   DeclarationName MethodName
     = Context.DeclarationNames.getCXXOperatorName(OO_Call);
+  DeclarationNameLoc MethodNameLoc;
+  MethodNameLoc.CXXOperatorName.BeginOpNameLoc
+    = Intro.Range.getBegin().getRawEncoding();
+  MethodNameLoc.CXXOperatorName.EndOpNameLoc
+    = Intro.Range.getEnd().getRawEncoding();
   CXXMethodDecl *Method
-    = CXXMethodDecl::Create(Context,
-                            Class,
-                            ParamInfo.getSourceRange().getEnd(),
-                            DeclarationNameInfo(MethodName,
-                                                /*NameLoc=*/SourceLocation()),
-                            MethodTy,
-                            MethodTyInfo,
+    = CXXMethodDecl::Create(Context, Class, EndLoc,
+                            DeclarationNameInfo(MethodName, 
+                                                Intro.Range.getBegin(),
+                                                MethodNameLoc),
+                            MethodTy, MethodTyInfo,
                             /*isStatic=*/false,
                             SC_None,
                             /*isInline=*/true,
                             /*isConstExpr=*/false,
-                            ParamInfo.getSourceRange().getEnd());
+                            EndLoc);
   Method->setAccess(AS_public);
   Class->addDecl(Method);
   Method->setLexicalDeclContext(DC); // FIXME: Minor hack.
@@ -4963,7 +4969,7 @@
   PushDeclContext(CurScope, Method);
     
   // Introduce the lambda scope.
-  PushLambdaScope(Class);
+  PushLambdaScope(Class, Method);
   LambdaScopeInfo *LSI = getCurLambda();
   if (Intro.Default == LCD_ByCopy)
     LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
@@ -5123,9 +5129,6 @@
   DiscardCleanupsInEvaluationContext();
   PopExpressionEvaluationContext();
 
-  // Leave the context of the lambda.
-  PopDeclContext();
-
   // FIXME: End-of-lambda checking
 
   // Collect information from the lambda scope.
@@ -5184,7 +5187,10 @@
       break;
     }
 
-    PopFunctionScopeInfo();
+    // C++ [expr.prim.lambda]p7:
+    //   The lambda-expression’s compound-statement yields the
+    //   function-body (8.4) of the function call operator [...].
+    ActOnFinishFunctionBody(LSI->CallOperator, Body, /*IsInstantation=*/false);
   }
 
   Expr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, 

Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp Wed Feb  8 14:17:14 2012
@@ -5,6 +5,6 @@
 };
 
 void capture_by_ref(NonCopyable nc, NonCopyable &ncr) {
-  [&nc] {}; // expected-error{{lambda expressions are not supported yet}}
-  [&ncr] {}; // expected-error{{lambda expressions are not supported yet}}
+  [&nc] () -> void {}; // expected-error{{lambda expressions are not supported yet}}
+  [&ncr] () -> void {}; // expected-error{{lambda expressions are not supported yet}}
 }

Added: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp?rev=150087&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp (added)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp Wed Feb  8 14:17:14 2012
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+
+// Check that analysis-based warnings work in lambda bodies.
+void analysis_based_warnings() {
+  []() -> int { }; // expected-warning{{control reaches end of non-void function}} \
+  // expected-error{{lambda expressions are not supported yet}}
+}
+
+// FIXME: Also check translation of captured vars to data members,
+// most of which isn't in the AST.
+
+

Propchange: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list