[cfe-commits] r147650 - in /cfe/trunk: include/clang/Sema/ScopeInfo.h include/clang/Sema/Sema.h lib/Parse/ParseExprCXX.cpp lib/Sema/Sema.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaType.cpp

Eli Friedman eli.friedman at gmail.com
Thu Jan 5 19:05:34 PST 2012


Author: efriedma
Date: Thu Jan  5 21:05:34 2012
New Revision: 147650

URL: http://llvm.org/viewvc/llvm-project?rev=147650&view=rev
Log:
More lambda work.  Fixes a minor bug Richard pointed out, makes lookup for lambda parameters work correctly, recording more information into the AST.


Modified:
    cfe/trunk/include/clang/Sema/ScopeInfo.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=147650&r1=147649&r2=147650&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Thu Jan  5 21:05:34 2012
@@ -180,9 +180,15 @@
   /// \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), 
-      NumExplicitCaptures(0), ThisCapture(0) 
+      NumExplicitCaptures(0), 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=147650&r1=147649&r2=147650&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jan  5 21:05:34 2012
@@ -164,6 +164,7 @@
   class BlockScopeInfo;
   class DelayedDiagnostic;
   class FunctionScopeInfo;
+  class LambdaScopeInfo;
   class TemplateDeductionInfo;
 }
 
@@ -780,6 +781,9 @@
   /// \brief Retrieve the current block, if any.
   sema::BlockScopeInfo *getCurBlock();
 
+  /// \brief Retrieve the current lambda expression, if any.
+  sema::LambdaScopeInfo *getCurLambda();
+
   /// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls
   SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
 

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=147650&r1=147649&r2=147650&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Jan  5 21:05:34 2012
@@ -792,6 +792,12 @@
                   Attr, DeclEndLoc);
   }
 
+  // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
+  // it.
+  ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope |
+                             Scope::BreakScope | Scope::ContinueScope |
+                             Scope::DeclScope);
+
   Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope());
 
   // Parse compound-statement.
@@ -801,11 +807,6 @@
     return ExprError();
   }
 
-  // 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();
 

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=147650&r1=147649&r2=147650&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Jan  5 21:05:34 2012
@@ -869,6 +869,13 @@
   return dyn_cast<BlockScopeInfo>(FunctionScopes.back());  
 }
 
+LambdaScopeInfo *Sema::getCurLambda() {
+  if (FunctionScopes.empty())
+    return 0;
+  
+  return dyn_cast<LambdaScopeInfo>(FunctionScopes.back());  
+}
+
 // Pin this vtable to this file.
 ExternalSemaSource::~ExternalSemaSource() {}
 

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=147650&r1=147649&r2=147650&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jan  5 21:05:34 2012
@@ -4782,7 +4782,7 @@
                                         Declarator &ParamInfo,
                                         Scope *CurScope) {
   DeclContext *DC = CurContext;
-  while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isNamespace()))
+  while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext()))
     DC = DC->getParent();
 
   // Start constructing the lambda class.
@@ -4795,8 +4795,26 @@
 
   // Build the call operator; we don't really have all the relevant information
   // at this point, but we need something to attach child declarations to.
+  QualType MethodTy;
   TypeSourceInfo *MethodTyInfo;
-  MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
+  if (ParamInfo.getNumTypeObjects() == 0) {
+    FunctionProtoType::ExtProtoInfo EPI;
+    EPI.TypeQuals |= DeclSpec::TQ_const;
+    MethodTy = Context.getFunctionType(Context.DependentTy,
+                                       /*Args=*/0, /*NumArgs=*/0, EPI);
+    MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
+  } else {
+    assert(ParamInfo.isFunctionDeclarator() &&
+           "lambda-declarator is a function");
+    DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getFunctionTypeInfo();
+    if (!FTI.hasMutableQualifier())
+      FTI.TypeQuals |= DeclSpec::TQ_const;
+    MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
+    // FIXME: Can these asserts actually fail?
+    assert(MethodTyInfo && "no type from lambda-declarator");
+    MethodTy = MethodTyInfo->getType();
+    assert(!MethodTy.isNull() && "no type from lambda declarator");
+  }
 
   DeclarationName MethodName
     = Context.DeclarationNames.getCXXOperatorName(OO_Call);
@@ -4806,7 +4824,7 @@
                             ParamInfo.getSourceRange().getEnd(),
                             DeclarationNameInfo(MethodName,
                                                 /*NameLoc=*/SourceLocation()),
-                            MethodTyInfo->getType(),
+                            MethodTy,
                             MethodTyInfo,
                             /*isStatic=*/false,
                             SC_None,
@@ -4817,6 +4835,19 @@
   Class->addDecl(Method);
   Method->setLexicalDeclContext(DC); // FIXME: Is this really correct?
 
+  ProcessDeclAttributes(CurScope, Method, ParamInfo);
+
+  // Introduce the lambda scope.
+  PushLambdaScope(Class);
+
+  // Enter a new evaluation context to insulate the block from any
+  // cleanups from the enclosing full-expression.
+  PushExpressionEvaluationContext(PotentiallyEvaluated);
+
+  PushDeclContext(CurScope, Method);
+
+  LambdaScopeInfo *LSI = getCurLambda();
+
   // Set the parameters on the decl, if specified.
   if (isa<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc())) {
     FunctionProtoTypeLoc Proto =
@@ -4825,21 +4856,30 @@
     CheckParmsForFunctionDef(Method->param_begin(),
                              Method->param_end(),
                              /*CheckParameterNames=*/false);
-  }
-
-  ProcessDeclAttributes(CurScope, Method, ParamInfo);
 
-  // FIXME: There's a bunch of missing checking etc;
-  // see ActOnBlockArguments
-
-  // Introduce the lambda scope.
-  PushLambdaScope(Class);
+    // Introduce our parameters into the function scope
+    for (unsigned p = 0, NumParams = Method->getNumParams(); p < NumParams; ++p) {
+      ParmVarDecl *Param = Method->getParamDecl(p);
+      Param->setOwningFunction(Method);
+
+      // If this has an identifier, add it to the scope stack.
+      if (Param->getIdentifier()) {
+        CheckShadow(CurScope, Param);
+
+        PushOnScopeChains(Param, CurScope);
+      }
+    }
+  }
 
-  // Enter a new evaluation context to insulate the block from any
-  // cleanups from the enclosing full-expression.
-  PushExpressionEvaluationContext(PotentiallyEvaluated);
+  const FunctionType *Fn = MethodTy->getAs<FunctionType>();
+  QualType RetTy = Fn->getResultType();
+  if (RetTy != Context.DependentTy) {
+    LSI->ReturnType = RetTy;
+    LSI->HasImplicitReturnType = true;
+  }
 
-  PushDeclContext(CurScope, Method);
+  // FIXME: Check return type is complete, !isObjCObjectType
+  
 }
 
 void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=147650&r1=147649&r2=147650&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jan  5 21:05:34 2012
@@ -2378,7 +2378,8 @@
     // top-level template type arguments.
     bool FreeFunction;
     if (!D.getCXXScopeSpec().isSet()) {
-      FreeFunction = (D.getContext() != Declarator::MemberContext ||
+      FreeFunction = ((D.getContext() != Declarator::MemberContext &&
+                       D.getContext() != Declarator::LambdaExprContext) ||
                       D.getDeclSpec().isFriendSpecified());
     } else {
       DeclContext *DC = S.computeDeclContext(D.getCXXScopeSpec());





More information about the cfe-commits mailing list