blob: 3e9e2102448a3a1758c8f3418354b3b176b00c46 [file] [log] [blame]
Douglas Gregor03dd13c2012-02-08 21:18:48 +00001//===--- SemaLambda.cpp - Semantic Analysis for C++11 Lambdas -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements semantic analysis for C++ lambda expressions.
11//
12//===----------------------------------------------------------------------===//
13#include "clang/Sema/DeclSpec.h"
14#include "clang/Sema/Initialization.h"
15#include "clang/Sema/Lookup.h"
16#include "clang/Sema/ScopeInfo.h"
17#include "clang/Sema/SemaInternal.h"
18#include "clang/AST/ExprCXX.h"
19using namespace clang;
20using namespace sema;
21
22void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
23 Declarator &ParamInfo,
24 Scope *CurScope) {
25 DeclContext *DC = CurContext;
26 while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext()))
27 DC = DC->getParent();
28
29 // Start constructing the lambda class.
30 CXXRecordDecl *Class = CXXRecordDecl::Create(Context, TTK_Class, DC,
31 Intro.Range.getBegin(),
32 /*IdLoc=*/SourceLocation(),
33 /*Id=*/0);
34 Class->startDefinition();
35 Class->setLambda(true);
36 CurContext->addDecl(Class);
37
38 // Build the call operator; we don't really have all the relevant information
39 // at this point, but we need something to attach child declarations to.
40 QualType MethodTy;
41 TypeSourceInfo *MethodTyInfo;
42 bool ExplicitParams = true;
43 SourceLocation EndLoc;
44 if (ParamInfo.getNumTypeObjects() == 0) {
45 // C++11 [expr.prim.lambda]p4:
46 // If a lambda-expression does not include a lambda-declarator, it is as
47 // if the lambda-declarator were ().
48 FunctionProtoType::ExtProtoInfo EPI;
49 EPI.TypeQuals |= DeclSpec::TQ_const;
50 MethodTy = Context.getFunctionType(Context.DependentTy,
51 /*Args=*/0, /*NumArgs=*/0, EPI);
52 MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
53 ExplicitParams = false;
54 EndLoc = Intro.Range.getEnd();
55 } else {
56 assert(ParamInfo.isFunctionDeclarator() &&
57 "lambda-declarator is a function");
58 DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getFunctionTypeInfo();
59
60 // C++11 [expr.prim.lambda]p5:
61 // This function call operator is declared const (9.3.1) if and only if
62 // the lambda-expression's parameter-declaration-clause is not followed
63 // by mutable. It is neither virtual nor declared volatile. [...]
64 if (!FTI.hasMutableQualifier())
65 FTI.TypeQuals |= DeclSpec::TQ_const;
66
67 // C++11 [expr.prim.lambda]p5:
68 // [...] Default arguments (8.3.6) shall not be specified in the
69 // parameter-declaration-clause of a lambda-declarator.
70 CheckExtraCXXDefaultArguments(ParamInfo);
71
72 MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
73 // FIXME: Can these asserts actually fail?
74 assert(MethodTyInfo && "no type from lambda-declarator");
75 MethodTy = MethodTyInfo->getType();
76 assert(!MethodTy.isNull() && "no type from lambda declarator");
77 EndLoc = ParamInfo.getSourceRange().getEnd();
78 }
79
80 // C++11 [expr.prim.lambda]p5:
81 // The closure type for a lambda-expression has a public inline function
82 // call operator (13.5.4) whose parameters and return type are described by
83 // the lambda-expression's parameter-declaration-clause and
84 // trailing-return-type respectively.
85 DeclarationName MethodName
86 = Context.DeclarationNames.getCXXOperatorName(OO_Call);
87 DeclarationNameLoc MethodNameLoc;
88 MethodNameLoc.CXXOperatorName.BeginOpNameLoc
89 = Intro.Range.getBegin().getRawEncoding();
90 MethodNameLoc.CXXOperatorName.EndOpNameLoc
91 = Intro.Range.getEnd().getRawEncoding();
92 CXXMethodDecl *Method
93 = CXXMethodDecl::Create(Context, Class, EndLoc,
94 DeclarationNameInfo(MethodName,
95 Intro.Range.getBegin(),
96 MethodNameLoc),
97 MethodTy, MethodTyInfo,
98 /*isStatic=*/false,
99 SC_None,
100 /*isInline=*/true,
101 /*isConstExpr=*/false,
102 EndLoc);
103 Method->setAccess(AS_public);
104 Class->addDecl(Method);
105 Method->setLexicalDeclContext(DC); // FIXME: Minor hack.
106
107 ProcessDeclAttributes(CurScope, Method, ParamInfo);
108
109 // Enter a new evaluation context to insulate the block from any
110 // cleanups from the enclosing full-expression.
111 PushExpressionEvaluationContext(PotentiallyEvaluated);
112
113 PushDeclContext(CurScope, Method);
114
115 // Introduce the lambda scope.
116 PushLambdaScope(Class, Method);
117 LambdaScopeInfo *LSI = getCurLambda();
118 if (Intro.Default == LCD_ByCopy)
119 LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
120 else if (Intro.Default == LCD_ByRef)
121 LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref;
122 LSI->IntroducerRange = Intro.Range;
123 LSI->ExplicitParams = ExplicitParams;
124 LSI->Mutable = (Method->getTypeQualifiers() & Qualifiers::Const) == 0;
125
126 // Handle explicit captures.
127 for (llvm::SmallVector<LambdaCapture, 4>::const_iterator
128 C = Intro.Captures.begin(),
129 E = Intro.Captures.end();
130 C != E; ++C) {
131 if (C->Kind == LCK_This) {
132 // C++11 [expr.prim.lambda]p8:
133 // An identifier or this shall not appear more than once in a
134 // lambda-capture.
135 if (LSI->isCXXThisCaptured()) {
136 Diag(C->Loc, diag::err_capture_more_than_once)
137 << "'this'"
138 << SourceRange(LSI->getCXXThisCapture().getLocation());
139 continue;
140 }
141
142 // C++11 [expr.prim.lambda]p8:
143 // If a lambda-capture includes a capture-default that is =, the
144 // lambda-capture shall not contain this [...].
145 if (Intro.Default == LCD_ByCopy) {
146 Diag(C->Loc, diag::err_this_capture_with_copy_default);
147 continue;
148 }
149
150 // C++11 [expr.prim.lambda]p12:
151 // If this is captured by a local lambda expression, its nearest
152 // enclosing function shall be a non-static member function.
153 QualType ThisCaptureType = getCurrentThisType();
154 if (ThisCaptureType.isNull()) {
155 Diag(C->Loc, diag::err_this_capture) << true;
156 continue;
157 }
158
159 CheckCXXThisCapture(C->Loc, /*Explicit=*/true);
160 continue;
161 }
162
163 assert(C->Id && "missing identifier for capture");
164
165 // C++11 [expr.prim.lambda]p8:
166 // If a lambda-capture includes a capture-default that is &, the
167 // identifiers in the lambda-capture shall not be preceded by &.
168 // If a lambda-capture includes a capture-default that is =, [...]
169 // each identifier it contains shall be preceded by &.
170 if (C->Kind == LCK_ByRef && Intro.Default == LCD_ByRef) {
171 Diag(C->Loc, diag::err_reference_capture_with_reference_default);
172 continue;
173 } else if (C->Kind == LCK_ByCopy && Intro.Default == LCD_ByCopy) {
174 Diag(C->Loc, diag::err_copy_capture_with_copy_default);
175 continue;
176 }
177
178 DeclarationNameInfo Name(C->Id, C->Loc);
179 LookupResult R(*this, Name, LookupOrdinaryName);
180 LookupName(R, CurScope);
181 if (R.isAmbiguous())
182 continue;
183 if (R.empty()) {
184 // FIXME: Disable corrections that would add qualification?
185 CXXScopeSpec ScopeSpec;
186 DeclFilterCCC<VarDecl> Validator;
187 if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, Validator))
188 continue;
189 }
190
191 // C++11 [expr.prim.lambda]p10:
192 // The identifiers in a capture-list are looked up using the usual rules
193 // for unqualified name lookup (3.4.1); each such lookup shall find a
194 // variable with automatic storage duration declared in the reaching
195 // scope of the local lambda expression.
196 // FIXME: Check reaching scope.
197 VarDecl *Var = R.getAsSingle<VarDecl>();
198 if (!Var) {
199 Diag(C->Loc, diag::err_capture_does_not_name_variable) << C->Id;
200 continue;
201 }
202
203 if (!Var->hasLocalStorage()) {
204 Diag(C->Loc, diag::err_capture_non_automatic_variable) << C->Id;
205 Diag(Var->getLocation(), diag::note_previous_decl) << C->Id;
206 continue;
207 }
208
209 // C++11 [expr.prim.lambda]p8:
210 // An identifier or this shall not appear more than once in a
211 // lambda-capture.
212 if (LSI->isCaptured(Var)) {
213 Diag(C->Loc, diag::err_capture_more_than_once)
214 << C->Id
215 << SourceRange(LSI->getCapture(Var).getLocation());
216 continue;
217 }
218
219 TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef :
220 TryCapture_ExplicitByVal;
221 TryCaptureVar(Var, C->Loc, Kind);
222 }
223 LSI->finishedExplicitCaptures();
224
225 // Set the parameters on the decl, if specified.
226 if (isa<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc())) {
227 FunctionProtoTypeLoc Proto =
228 cast<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc());
229 Method->setParams(Proto.getParams());
230 CheckParmsForFunctionDef(Method->param_begin(),
231 Method->param_end(),
232 /*CheckParameterNames=*/false);
233
234 // Introduce our parameters into the function scope
235 for (unsigned p = 0, NumParams = Method->getNumParams(); p < NumParams; ++p) {
236 ParmVarDecl *Param = Method->getParamDecl(p);
237 Param->setOwningFunction(Method);
238
239 // If this has an identifier, add it to the scope stack.
240 if (Param->getIdentifier()) {
241 CheckShadow(CurScope, Param);
242
243 PushOnScopeChains(Param, CurScope);
244 }
245 }
246 }
247
248 const FunctionType *Fn = MethodTy->getAs<FunctionType>();
249 QualType RetTy = Fn->getResultType();
250 if (RetTy != Context.DependentTy) {
251 LSI->ReturnType = RetTy;
252 } else {
253 LSI->HasImplicitReturnType = true;
254 }
255
256 // FIXME: Check return type is complete, !isObjCObjectType
257
258}
259
260void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
261 // Leave the expression-evaluation context.
262 DiscardCleanupsInEvaluationContext();
263 PopExpressionEvaluationContext();
264
265 // Leave the context of the lambda.
266 PopDeclContext();
267 PopFunctionScopeInfo();
268}
269
270ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc,
271 Stmt *Body, Scope *CurScope) {
272 // Leave the expression-evaluation context.
273 DiscardCleanupsInEvaluationContext();
274 PopExpressionEvaluationContext();
275
276 // FIXME: End-of-lambda checking
277
278 // Collect information from the lambda scope.
279 llvm::SmallVector<LambdaExpr::Capture, 4> Captures;
280 llvm::SmallVector<Expr *, 4> CaptureInits;
281 LambdaCaptureDefault CaptureDefault;
282 CXXRecordDecl *Class;
283 SourceRange IntroducerRange;
284 bool ExplicitParams;
285 {
286 LambdaScopeInfo *LSI = getCurLambda();
287 Class = LSI->Lambda;
288 IntroducerRange = LSI->IntroducerRange;
289 ExplicitParams = LSI->ExplicitParams;
290
291 // Translate captures.
292 for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
293 LambdaScopeInfo::Capture From = LSI->Captures[I];
294 assert(!From.isBlockCapture() && "Cannot capture __block variables");
295 bool IsImplicit = I >= LSI->NumExplicitCaptures;
296
297 // Handle 'this' capture.
298 if (From.isThisCapture()) {
299 Captures.push_back(LambdaExpr::Capture(From.getLocation(),
300 IsImplicit,
301 LCK_This));
302 CaptureInits.push_back(new (Context) CXXThisExpr(From.getLocation(),
303 getCurrentThisType(),
304 /*isImplicit=*/true));
305 continue;
306 }
307
308 VarDecl *Var = From.getVariable();
309 // FIXME: Handle pack expansions.
310 LambdaCaptureKind Kind = From.isCopyCapture()? LCK_ByCopy : LCK_ByRef;
311 Captures.push_back(LambdaExpr::Capture(From.getLocation(), IsImplicit,
312 Kind, Var));
313 CaptureInits.push_back(From.getCopyExpr());
314 }
315
316 switch (LSI->ImpCaptureStyle) {
317 case CapturingScopeInfo::ImpCap_None:
318 CaptureDefault = LCD_None;
319 break;
320
321 case CapturingScopeInfo::ImpCap_LambdaByval:
322 CaptureDefault = LCD_ByCopy;
323 break;
324
325 case CapturingScopeInfo::ImpCap_LambdaByref:
326 CaptureDefault = LCD_ByRef;
327 break;
328
329 case CapturingScopeInfo::ImpCap_Block:
330 llvm_unreachable("block capture in lambda");
331 break;
332 }
333
334 // C++ [expr.prim.lambda]p7:
335 // The lambda-expression's compound-statement yields the
336 // function-body (8.4) of the function call operator [...].
337 ActOnFinishFunctionBody(LSI->CallOperator, Body, /*IsInstantation=*/false);
338 }
339
340 Expr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
341 CaptureDefault, Captures, ExplicitParams,
342 CaptureInits, Body->getLocEnd());
343 (void)Lambda;
344 Diag(StartLoc, diag::err_lambda_unsupported);
345 return ExprError();
346}