[cfe-commits] r150087 - in /cfe/trunk: include/clang/AST/ExprCXX.h include/clang/Sema/ScopeInfo.h include/clang/Sema/Sema.h lib/Sema/Sema.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
Douglas Gregor
dgregor at apple.com
Wed Feb 8 12:17:15 PST 2012
Author: dgregor
Date: Wed Feb 8 14:17:14 2012
New Revision: 150087
URL: http://llvm.org/viewvc/llvm-project?rev=150087&view=rev
Log:
When completing a lambda expression, make sure to check and attach the
body of the lambda to the function call operator.
Added:
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp (with props)
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/include/clang/Sema/ScopeInfo.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Feb 8 14:17:14 2012
@@ -1226,8 +1226,7 @@
}
/// \brief Retrieve the iterator pointing one past the last
- /// initialization argument for this lambda expression (which
- /// initializes the first capture field).
+ /// initialization argument for this lambda expression.
capture_init_iterator capture_init_end() const {
return capture_init_begin() + NumCaptures;
}
Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Wed Feb 8 14:17:14 2012
@@ -280,6 +280,9 @@
/// \brief The class that describes the lambda.
CXXRecordDecl *Lambda;
+ /// \brief The class that describes the lambda.
+ CXXMethodDecl *CallOperator;
+
/// \brief Source range covering the lambda introducer [...].
SourceRange IntroducerRange;
@@ -292,9 +295,10 @@
/// \brief Whether the (empty) parameter list is explicit.
bool ExplicitParams;
- LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda)
+ LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
+ CXXMethodDecl *CallOperator)
: CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
- NumExplicitCaptures(0), Mutable(false)
+ CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false)
{
Kind = SK_Lambda;
}
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Feb 8 14:17:14 2012
@@ -732,7 +732,7 @@
void PushFunctionScope();
void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
- void PushLambdaScope(CXXRecordDecl *Lambda);
+ void PushLambdaScope(CXXRecordDecl *Lambda, CXXMethodDecl *CallOperator);
void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP =0,
const Decl *D = 0, const BlockExpr *blkExpr = 0);
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Wed Feb 8 14:17:14 2012
@@ -831,8 +831,10 @@
BlockScope, Block));
}
-void Sema::PushLambdaScope(CXXRecordDecl *Lambda) {
- FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda));
+void Sema::PushLambdaScope(CXXRecordDecl *Lambda,
+ CXXMethodDecl *CallOperator) {
+ FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda,
+ CallOperator));
}
void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Feb 8 14:17:14 2012
@@ -7236,7 +7236,8 @@
computeNRVO(Body, getCurFunction());
}
- assert(FD == getCurFunctionDecl() && "Function parsing confused");
+ assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) &&
+ "Function parsing confused");
} else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
assert(MD == getCurMethodDecl() && "Method parsing confused");
MD->setBody(Body);
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Feb 8 14:17:14 2012
@@ -9722,8 +9722,6 @@
// of the copy/move done to move a __block variable to the heap.
type.addConst();
- // FIXME: Add an initialized entity for lambda capture.
- // FIXME: Won't work for arrays, although we do need this behavior.
Expr *declRef = new (Context) DeclRefExpr(var, type, VK_LValue, loc);
ExprResult result =
PerformCopyInitialization(
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Feb 8 14:17:14 2012
@@ -4896,6 +4896,7 @@
QualType MethodTy;
TypeSourceInfo *MethodTyInfo;
bool ExplicitParams = true;
+ SourceLocation EndLoc;
if (ParamInfo.getNumTypeObjects() == 0) {
// C++11 [expr.prim.lambda]p4:
// If a lambda-expression does not include a lambda-declarator, it is as
@@ -4906,6 +4907,7 @@
/*Args=*/0, /*NumArgs=*/0, EPI);
MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
ExplicitParams = false;
+ EndLoc = Intro.Range.getEnd();
} else {
assert(ParamInfo.isFunctionDeclarator() &&
"lambda-declarator is a function");
@@ -4928,6 +4930,7 @@
assert(MethodTyInfo && "no type from lambda-declarator");
MethodTy = MethodTyInfo->getType();
assert(!MethodTy.isNull() && "no type from lambda declarator");
+ EndLoc = ParamInfo.getSourceRange().getEnd();
}
// C++11 [expr.prim.lambda]p5:
@@ -4937,19 +4940,22 @@
// trailing-return-type respectively.
DeclarationName MethodName
= Context.DeclarationNames.getCXXOperatorName(OO_Call);
+ DeclarationNameLoc MethodNameLoc;
+ MethodNameLoc.CXXOperatorName.BeginOpNameLoc
+ = Intro.Range.getBegin().getRawEncoding();
+ MethodNameLoc.CXXOperatorName.EndOpNameLoc
+ = Intro.Range.getEnd().getRawEncoding();
CXXMethodDecl *Method
- = CXXMethodDecl::Create(Context,
- Class,
- ParamInfo.getSourceRange().getEnd(),
- DeclarationNameInfo(MethodName,
- /*NameLoc=*/SourceLocation()),
- MethodTy,
- MethodTyInfo,
+ = CXXMethodDecl::Create(Context, Class, EndLoc,
+ DeclarationNameInfo(MethodName,
+ Intro.Range.getBegin(),
+ MethodNameLoc),
+ MethodTy, MethodTyInfo,
/*isStatic=*/false,
SC_None,
/*isInline=*/true,
/*isConstExpr=*/false,
- ParamInfo.getSourceRange().getEnd());
+ EndLoc);
Method->setAccess(AS_public);
Class->addDecl(Method);
Method->setLexicalDeclContext(DC); // FIXME: Minor hack.
@@ -4963,7 +4969,7 @@
PushDeclContext(CurScope, Method);
// Introduce the lambda scope.
- PushLambdaScope(Class);
+ PushLambdaScope(Class, Method);
LambdaScopeInfo *LSI = getCurLambda();
if (Intro.Default == LCD_ByCopy)
LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
@@ -5123,9 +5129,6 @@
DiscardCleanupsInEvaluationContext();
PopExpressionEvaluationContext();
- // Leave the context of the lambda.
- PopDeclContext();
-
// FIXME: End-of-lambda checking
// Collect information from the lambda scope.
@@ -5184,7 +5187,10 @@
break;
}
- PopFunctionScopeInfo();
+ // C++ [expr.prim.lambda]p7:
+ // The lambda-expressionâs compound-statement yields the
+ // function-body (8.4) of the function call operator [...].
+ ActOnFinishFunctionBody(LSI->CallOperator, Body, /*IsInstantation=*/false);
}
Expr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp?rev=150087&r1=150086&r2=150087&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp Wed Feb 8 14:17:14 2012
@@ -5,6 +5,6 @@
};
void capture_by_ref(NonCopyable nc, NonCopyable &ncr) {
- [&nc] {}; // expected-error{{lambda expressions are not supported yet}}
- [&ncr] {}; // expected-error{{lambda expressions are not supported yet}}
+ [&nc] () -> void {}; // expected-error{{lambda expressions are not supported yet}}
+ [&ncr] () -> void {}; // expected-error{{lambda expressions are not supported yet}}
}
Added: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp?rev=150087&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp (added)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp Wed Feb 8 14:17:14 2012
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+
+// Check that analysis-based warnings work in lambda bodies.
+void analysis_based_warnings() {
+ []() -> int { }; // expected-warning{{control reaches end of non-void function}} \
+ // expected-error{{lambda expressions are not supported yet}}
+}
+
+// FIXME: Also check translation of captured vars to data members,
+// most of which isn't in the AST.
+
+
Propchange: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list