Add an explicit LambdaExprContext to Declarator, to parallel BlockLiteralContext...
authorEli Friedman <eli.friedman@gmail.com>
Wed, 4 Jan 2012 04:41:38 +0000 (04:41 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 4 Jan 2012 04:41:38 +0000 (04:41 +0000)
llvm-svn: 147522

clang/include/clang/Sema/DeclSpec.h
clang/lib/Parse/ParseExprCXX.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaType.cpp

index 7dc8f29..44823c8 100644 (file)
@@ -1416,6 +1416,7 @@ public:
     CXXCatchContext,     // C++ catch exception-declaration
     ObjCCatchContext,    // Objective-C catch exception-declaration
     BlockLiteralContext,  // Block literal declarator.
+    LambdaExprContext,   // Lambda-expression declarator.
     TemplateTypeArgContext, // Template type argument.
     AliasDeclContext,    // C++0x alias-declaration.
     AliasTemplateContext // C++0x alias-declaration template.
@@ -1582,6 +1583,7 @@ public:
     case CXXCatchContext:
     case ObjCCatchContext:
     case BlockLiteralContext:
+    case LambdaExprContext:
     case TemplateTypeArgContext:
       return true;
     }
@@ -1612,6 +1614,7 @@ public:
     case ObjCParameterContext:
     case ObjCResultContext:
     case BlockLiteralContext:
+    case LambdaExprContext:
     case TemplateTypeArgContext:
       return false;
     }
@@ -1643,6 +1646,7 @@ public:
     case AliasDeclContext:
     case AliasTemplateContext:
     case BlockLiteralContext:
+    case LambdaExprContext:
     case TemplateTypeArgContext:
       return false;
     }
index 4776ab9..96f8709 100644 (file)
@@ -715,7 +715,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
 
   // Parse lambda-declarator[opt].
   DeclSpec DS(AttrFactory);
-  Declarator D(DS, Declarator::BlockLiteralContext);
+  Declarator D(DS, Declarator::LambdaExprContext);
 
   if (Tok.is(tok::l_paren)) {
     ParseScope PrototypeScope(this,
index 67e1c2f..e53e5cd 100644 (file)
@@ -4780,7 +4780,6 @@ Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
 
 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
@@ -4789,7 +4788,10 @@ void Sema::ActOnLambdaStart(SourceLocation StartLoc, Scope *CurScope) {
 }
 
 void Sema::ActOnLambdaArguments(Declarator &ParamInfo, Scope *CurScope) {
-  // FIXME: Implement
+  TypeSourceInfo *MethodTyInfo;
+  MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
+
+  // FIXME: Build CXXMethodDecl
 }
 
 void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
index f4b82fc..a3b6768 100644 (file)
@@ -640,7 +640,10 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
     
     // If this is a missing declspec in a block literal return context, then it
     // is inferred from the return statements inside the block.
-    if (isOmittedBlockReturnType(declarator)) {
+    // The declspec is always missing in a lambda expr context; it is either
+    // specified with a trailing return type or inferred.
+    if (declarator.getContext() == Declarator::LambdaExprContext ||
+        isOmittedBlockReturnType(declarator)) {
       Result = Context.DependentTy;
       break;
     }
@@ -1785,6 +1788,9 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
     case Declarator::KNRTypeListContext:
       llvm_unreachable("K&R type lists aren't allowed in C++");
       break;
+    case Declarator::LambdaExprContext:
+      llvm_unreachable("Can't specify a type specifier in lambda grammar");
+      break;
     case Declarator::ObjCParameterContext:
     case Declarator::ObjCResultContext:
     case Declarator::PrototypeContext:
@@ -1875,6 +1881,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
     case Declarator::BlockContext:
     case Declarator::ForContext:
     case Declarator::BlockLiteralContext:
+    case Declarator::LambdaExprContext:
       // C++0x [dcl.type]p3:
       //   A type-specifier-seq shall not define a class or enumeration unless
       //   it appears in the type-id of an alias-declaration (7.1.3) that is not
@@ -2058,7 +2065,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
                  diag::err_trailing_return_in_parens)
               << T << D.getDeclSpec().getSourceRange();
             D.setInvalidType(true);
-          } else if (T.hasQualifiers() || !isa<AutoType>(T)) {
+          } else if (D.getContext() != Declarator::LambdaExprContext &&
+                     (T.hasQualifiers() || !isa<AutoType>(T))) {
             S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
                  diag::err_trailing_return_without_auto)
               << T << D.getDeclSpec().getSourceRange();
@@ -2578,6 +2586,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
     case Declarator::CXXCatchContext:
     case Declarator::ObjCCatchContext:
     case Declarator::BlockLiteralContext:
+    case Declarator::LambdaExprContext:
     case Declarator::TemplateTypeArgContext:
       // FIXME: We may want to allow parameter packs in block-literal contexts
       // in the future.