diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-01-06 03:05:34 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-01-06 03:05:34 +0000 |
commit | 906a7e1c0f272f7e539c82dda01f4644031ce637 (patch) | |
tree | 6b517623085dbc5a155603060b68d458e1211a74 /lib/Sema/SemaExprCXX.cpp | |
parent | 2f0e88a87cea6d21429d9f5c0b1c53f24caf77cf (diff) |
More lambda work. Fixes a minor bug Richard pointed out, makes lookup for lambda parameters work correctly, recording more information into the AST.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147650 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index fd47dc75b2..0b1dcbda4f 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4782,7 +4782,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, 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 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, // 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 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, ParamInfo.getSourceRange().getEnd(), DeclarationNameInfo(MethodName, /*NameLoc=*/SourceLocation()), - MethodTyInfo->getType(), + MethodTy, MethodTyInfo, /*isStatic=*/false, SC_None, @@ -4817,6 +4835,19 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, 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 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, CheckParmsForFunctionDef(Method->param_begin(), Method->param_end(), /*CheckParameterNames=*/false); - } - ProcessDeclAttributes(CurScope, Method, ParamInfo); + // 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); - // FIXME: There's a bunch of missing checking etc; - // see ActOnBlockArguments + // If this has an identifier, add it to the scope stack. + if (Param->getIdentifier()) { + CheckShadow(CurScope, Param); - // Introduce the lambda scope. - PushLambdaScope(Class); + 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) { |