[cfe-commits] r147515 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaExprCXX.cpp test/Parser/cxx0x-attributes.cpp test/Parser/cxx0x-lambda-expressions.cpp test/Parser/objcxx0x-lambda-expressions.mm test/SemaCXX/cxx98-compat.cpp

Eli Friedman eli.friedman at gmail.com
Tue Jan 3 18:40:40 PST 2012


Author: efriedma
Date: Tue Jan  3 20:40:39 2012
New Revision: 147515

URL: http://llvm.org/viewvc/llvm-project?rev=147515&view=rev
Log:
Stub out the Sema interface for lambda expressions, and change the parser to use it.  Unconditionally error on lambda expressions because they don't work in any meaningful way yet.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/Parser/cxx0x-attributes.cpp
    cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp
    cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm
    cfe/trunk/test/SemaCXX/cxx98-compat.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jan  3 20:40:39 2012
@@ -3984,6 +3984,8 @@
 def err_return_in_constructor_handler : Error<
   "return in the catch of a function try block of a constructor is illegal">;
 
+def err_lambda_unsupported : Error<"lambda expressions are not supported yet">;
+
 def err_operator_arrow_circular : Error<
   "circular pointer delegation detected">;
 def err_pseudo_dtor_base_not_scalar : Error<

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jan  3 20:40:39 2012
@@ -3449,6 +3449,23 @@
   /// initializer for the declaration 'Dcl'.
   void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl);
 
+  /// ActOnLambdaStart - This callback is invoked when a lambda expression is
+  /// started.
+  void ActOnLambdaStart(SourceLocation StartLoc, Scope *CurScope);
+
+  /// ActOnLambdaArguments - This callback allows processing of lambda arguments.
+  /// If there are no arguments, this is still invoked.
+  void ActOnLambdaArguments(Declarator &ParamInfo, Scope *CurScope);
+
+  /// ActOnLambdaError - If there is an error parsing a lambda, this callback
+  /// is invoked to pop the information about the lambda from the action impl.
+  void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope);
+
+  /// ActOnLambdaExpr - This is called when the body of a lambda expression
+  /// was successfully completed.
+  ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
+                             Scope *CurScope);
+
   // ParseObjCStringLiteral - Parse Objective-C string literals.
   ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
                                     Expr **Strings,

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Jan  3 20:40:39 2012
@@ -1132,8 +1132,13 @@
   case tok::l_square:
     if (getLang().CPlusPlus0x) {
       if (getLang().ObjC1) {
+        // C++11 lambda expressions and Objective-C message sends both start with a
+        // square bracket.  There are three possibilities here:
+        // we have a valid lambda expression, we have an invalid lambda
+        // expression, or we have something that doesn't appear to be a lambda.
+        // If we're in the last case, we fall back to ParseObjCMessageExpression.
         Res = TryParseLambdaExpression();
-        if (Res.isInvalid())
+        if (!Res.isInvalid() && !Res.get())
           Res = ParseObjCMessageExpression();
         break;
       }

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Jan  3 20:40:39 2012
@@ -14,6 +14,7 @@
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
 #include "RAIIObjectsForParser.h"
+#include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ParsedTemplate.h"
@@ -563,6 +564,9 @@
   if (DiagID) {
     Diag(Tok, DiagID.getValue());
     SkipUntil(tok::r_square);
+    SkipUntil(tok::l_brace);
+    SkipUntil(tok::r_brace);
+    return ExprError();
   }
 
   return ParseLambdaExpressionAfterIntroducer(Intro);
@@ -591,14 +595,21 @@
     return ParseLambdaExpression();
   }
 
-  // If lookahead indicates this is an Objective-C message...
+  // If lookahead indicates an ObjC message send...
+  // [identifier identifier
   if (Next.is(tok::identifier) && After.is(tok::identifier)) {
-    return ExprError();
+    return ExprEmpty();
   }
 
+  // Here, we're stuck: lambda introducers and Objective-C message sends are
+  // unambiguous, but it requires arbitrary lookhead.  [a,b,c,d,e,f,g] is a
+  // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send.  Instead of
+  // writing two routines to parse a lambda introducer, just try to parse
+  // a lambda introducer first, and fall back if that fails.
+  // (TryParseLambdaIntroducer never produces any diagnostic output.)
   LambdaIntroducer Intro;
   if (TryParseLambdaIntroducer(Intro))
-    return ExprError();
+    return ExprEmpty();
   return ParseLambdaExpressionAfterIntroducer(Intro);
 }
 
@@ -694,11 +705,17 @@
 /// expression.
 ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
                      LambdaIntroducer &Intro) {
-  Diag(Intro.Range.getBegin(), diag::warn_cxx98_compat_lambda);
+  SourceLocation LambdaBeginLoc = Intro.Range.getBegin();
+  Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda);
+
+  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
+                                "lambda expression parsing");
+
+  Actions.ActOnLambdaStart(LambdaBeginLoc, getCurScope());
 
   // Parse lambda-declarator[opt].
   DeclSpec DS(AttrFactory);
-  Declarator D(DS, Declarator::PrototypeContext);
+  Declarator D(DS, Declarator::BlockLiteralContext);
 
   if (Tok.is(tok::l_paren)) {
     ParseScope PrototypeScope(this,
@@ -775,24 +792,32 @@
                                            DeclLoc, DeclEndLoc, D,
                                            TrailingReturnType),
                   Attr, DeclEndLoc);
+
+     // Inform sema that we are starting a block.
+     Actions.ActOnLambdaArguments(D, getCurScope());
   }
 
   // Parse compound-statement.
-  if (Tok.is(tok::l_brace)) {
-    // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
-    // it.
-    ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope |
-                               Scope::BreakScope | Scope::ContinueScope |
-                               Scope::DeclScope);
-
-    ParseCompoundStatementBody();
-
-    BodyScope.Exit();
-  } else {
+  if (!Tok.is(tok::l_brace)) {
     Diag(Tok, diag::err_expected_lambda_body);
+    Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
+    return ExprError();
   }
 
-  return ExprEmpty();
+  // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
+  // it.
+  ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope |
+                             Scope::BreakScope | Scope::ContinueScope |
+                             Scope::DeclScope);
+  StmtResult Stmt(ParseCompoundStatementBody());
+  BodyScope.Exit();
+
+   if (!Stmt.isInvalid())
+     return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.take(),
+                                    getCurScope());
+ 
+   Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
+   return ExprError();
 }
 
 /// ParseCXXCasts - This handles the various ways to cast expressions to another

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Jan  3 20:40:39 2012
@@ -4774,3 +4774,38 @@
   return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo);
 }
 
+//===----------------------------------------------------------------------===//
+// Lambdas.
+//===----------------------------------------------------------------------===//
+
+void Sema::ActOnLambdaStart(SourceLocation StartLoc, Scope *CurScope) {
+  // FIXME: Add lambda-scope
+  // FIXME: Build lambda-decl
+  // FIXME: PushDeclContext
+
+  // Enter a new evaluation context to insulate the block from any
+  // cleanups from the enclosing full-expression.
+  PushExpressionEvaluationContext(PotentiallyEvaluated);  
+}
+
+void Sema::ActOnLambdaArguments(Declarator &ParamInfo, Scope *CurScope) {
+  // FIXME: Implement
+}
+
+void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
+  // Leave the expression-evaluation context.
+  DiscardCleanupsInEvaluationContext();
+  PopExpressionEvaluationContext();
+
+  // Leave the context of the lambda.
+  // FIXME: PopDeclContext
+  // FIXME: Pop lambda-scope
+}
+
+ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc,
+                                 Stmt *Body, Scope *CurScope) {
+  // FIXME: Implement
+  Diag(StartLoc, diag::err_lambda_unsupported);
+  ActOnLambdaError(StartLoc, CurScope);
+  return ExprError();
+}

Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Tue Jan  3 20:40:39 2012
@@ -20,7 +20,7 @@
 unsigned [[]] int attr_in_decl_spec; // expected-error {{expected unqualified-id}}
 int & [[]] ref_attr = after_attr; // expected-error {{an attribute list cannot appear here}}
 class foo {
-  void after_const_attr () const [[]]; // expected-error {{expected body of lambda expression}} expected-error {{array has incomplete element type 'void'}}
+  void after_const_attr () const [[]]; // expected-error {{expected body of lambda expression}}
 };
 extern "C++" [[]] { } // expected-error {{an attribute list cannot appear here}}
 [[]] template <typename T> void before_template_attr (); // expected-error {{an attribute list cannot appear here}}

Modified: cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp Tue Jan  3 20:40:39 2012
@@ -12,13 +12,13 @@
     [&this] {}; // expected-error {{'this' cannot be captured by reference}}
     [&,] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
     [=,] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
-    [] {};
-    [=] (int i) {};
-    [&] (int) mutable -> void {};
-    [foo,bar] () { return 3; };
-    [=,&foo] () {};
-    [&,foo] () {};
-    [this] () {};
+    [] {}; // 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}}
+    [=,&foo] () {}; // 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}}
 
     return 1;
   }

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=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm (original)
+++ cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm Tue Jan  3 20:40:39 2012
@@ -11,15 +11,15 @@
     []; // expected-error {{expected body of lambda expression}}
     [=,foo+] {}; // expected-error {{expected ',' or ']' in lambda capture list}}
     [&this] {}; // expected-error {{address expression must be an lvalue}}
-    [] {};
-    [=] (int i) {};
-    [&] (int) mutable -> void {};
+    [] {}; // 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}}
     // FIXME: this error occurs because we do not yet handle lambda scopes
     // properly. I did not anticipate it because I thought it was a semantic (not
     // syntactic) check.
-    [foo,bar] () { return 3; }; // expected-error {{void function 'f' should not return a value}}
-    [=,&foo] () {};
-    [this] () {};
+    [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/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=147515&r1=147514&r2=147515&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Tue Jan  3 20:40:39 2012
@@ -34,7 +34,8 @@
 }
 
 void Lambda() {
-  []{}; // expected-warning {{lambda expressions are incompatible with C++98}}
+  // FIXME: Enable when lambdas are minimally working.
+  //[]{}; // FIXME-warning {{lambda expressions are incompatible with C++98}}
 }
 
 int InitList() {





More information about the cfe-commits mailing list