aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-01-05 03:35:19 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-01-05 03:35:19 +0000
commitec9ea7200718478e8a976529defbe21942a11c9c (patch)
tree52de9c7edea7849591dbf5b5438dbc0a46748293 /lib/Sema/SemaExprCXX.cpp
parentedb9459c43dec5f376020f2b53833dee6549e11d (diff)
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
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r--lib/Sema/SemaExprCXX.cpp72
1 files changed, 60 insertions, 12 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e53e5cda62..fd47dc75b2 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -4778,20 +4778,68 @@ Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
// 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();
+
+ // 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);
+
+ // 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);
+
+ 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);
-}
-
-void Sema::ActOnLambdaArguments(Declarator &ParamInfo, Scope *CurScope) {
- TypeSourceInfo *MethodTyInfo;
- MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
+ PushExpressionEvaluationContext(PotentiallyEvaluated);
- // FIXME: Build CXXMethodDecl
+ PushDeclContext(CurScope, Method);
}
void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
@@ -4800,8 +4848,8 @@ void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
PopExpressionEvaluationContext();
// Leave the context of the lambda.
- // FIXME: PopDeclContext
- // FIXME: Pop lambda-scope
+ PopDeclContext();
+ PopFunctionScopeInfo();
}
ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc,