aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.cpp7
-rw-r--r--lib/Sema/SemaExprCXX.cpp66
-rw-r--r--lib/Sema/SemaType.cpp3
3 files changed, 62 insertions, 14 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 6a77d8c673..4ab960de0e 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -869,6 +869,13 @@ BlockScopeInfo *Sema::getCurBlock() {
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() {}
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) {
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index a3b6768961..3bdb3b6d2c 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2378,7 +2378,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// 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());