More lambda work. Tweak the Sema interface slightly. Start adding the pieces to build the lambda class and its call operator. Create an actual scope for the lambda body.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147595 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e53e5cd..fd47dc7 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -4778,20 +4778,68 @@
// Lambdas.
//===----------------------------------------------------------------------===//
-void Sema::ActOnLambdaStart(SourceLocation StartLoc, Scope *CurScope) {
- // FIXME: Add lambda-scope
- // FIXME: PushDeclContext
+void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
+ Declarator &ParamInfo,
+ Scope *CurScope) {
+ DeclContext *DC = CurContext;
+ while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isNamespace()))
+ DC = DC->getParent();
- // Enter a new evaluation context to insulate the block from any
- // cleanups from the enclosing full-expression.
- PushExpressionEvaluationContext(PotentiallyEvaluated);
-}
+ // Start constructing the lambda class.
+ CXXRecordDecl *Class = CXXRecordDecl::Create(Context, TTK_Class, DC,
+ Intro.Range.getBegin(),
+ /*IdLoc=*/SourceLocation(),
+ /*Id=*/0);
+ Class->startDefinition();
+ CurContext->addDecl(Class);
-void Sema::ActOnLambdaArguments(Declarator &ParamInfo, Scope *CurScope) {
+ // 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.
TypeSourceInfo *MethodTyInfo;
MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
- // FIXME: Build CXXMethodDecl
+ DeclarationName MethodName
+ = Context.DeclarationNames.getCXXOperatorName(OO_Call);
+ CXXMethodDecl *Method
+ = CXXMethodDecl::Create(Context,
+ Class,
+ ParamInfo.getSourceRange().getEnd(),
+ DeclarationNameInfo(MethodName,
+ /*NameLoc=*/SourceLocation()),
+ MethodTyInfo->getType(),
+ MethodTyInfo,
+ /*isStatic=*/false,
+ SC_None,
+ /*isInline=*/true,
+ /*isConstExpr=*/false,
+ ParamInfo.getSourceRange().getEnd());
+ Method->setAccess(AS_public);
+ Class->addDecl(Method);
+ Method->setLexicalDeclContext(DC); // FIXME: Is this really correct?
+
+ // Set the parameters on the decl, if specified.
+ if (isa<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc())) {
+ FunctionProtoTypeLoc Proto =
+ cast<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc());
+ Method->setParams(Proto.getParams());
+ 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);
+
+ // Enter a new evaluation context to insulate the block from any
+ // cleanups from the enclosing full-expression.
+ PushExpressionEvaluationContext(PotentiallyEvaluated);
+
+ PushDeclContext(CurScope, Method);
}
void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
@@ -4800,8 +4848,8 @@
PopExpressionEvaluationContext();
// Leave the context of the lambda.
- // FIXME: PopDeclContext
- // FIXME: Pop lambda-scope
+ PopDeclContext();
+ PopFunctionScopeInfo();
}
ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc,