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 | 4817cf72f68324ba1a0683fbe4e7973793c40b95 (patch) | |
tree | 90661837fbe4750fc8db00e1351c666b22830cd6 /clang/lib/Sema/SemaExprCXX.cpp | |
parent | b3851f5ca15e7b3d0c8a272b1bd4d58bf99fedac (diff) | |
download | bcm5719-llvm-4817cf72f68324ba1a0683fbe4e7973793c40b95.tar.gz bcm5719-llvm-4817cf72f68324ba1a0683fbe4e7973793c40b95.zip |
More lambda work. Fixes a minor bug Richard pointed out, makes lookup for lambda parameters work correctly, recording more information into the AST.
llvm-svn: 147650
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index fd47dc75b21..0b1dcbda4ff 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/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) { |