[cfe-commits] r150725 - in /cfe/trunk: lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
Douglas Gregor
dgregor at apple.com
Thu Feb 16 13:36:19 PST 2012
Author: dgregor
Date: Thu Feb 16 15:36:18 2012
New Revision: 150725
URL: http://llvm.org/viewvc/llvm-project?rev=150725&view=rev
Log:
Lambda closure types are always considered to be like "local" classes,
even if they are not within a function scope. Teach template
instantiation to treat them as such, and make sure that we have a
local instantiation scope when instantiating default arguments and
static data members.
Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150725&r1=150724&r2=150725&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Feb 16 15:36:18 2012
@@ -3128,6 +3128,7 @@
// the semantic constraints are checked, at the point where the
// default argument expression appears.
ContextRAII SavedContext(*this, FD);
+ LocalInstantiationScope Local(*this);
Result = SubstExpr(UninstExpr, ArgList);
}
if (Result.isInvalid())
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=150725&r1=150724&r2=150725&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Feb 16 15:36:18 2012
@@ -2629,7 +2629,8 @@
// Enter the scope of this instantiation. We don't use
// PushDeclContext because we don't have a scope.
ContextRAII previousContext(*this, Var->getDeclContext());
-
+ LocalInstantiationScope Local(*this);
+
VarDecl *OldVar = Var;
Var = cast_or_null<VarDecl>(SubstDecl(Def, Var->getDeclContext(),
getTemplateInstantiationArgs(Var)));
@@ -2644,7 +2645,8 @@
DeclGroupRef DG(Var);
Consumer.HandleTopLevelDecl(DG);
}
-
+ Local.Exit();
+
if (Recursive) {
// Define any newly required vtables.
DefineUsedVTables();
@@ -3096,7 +3098,8 @@
DeclContext *ParentDC = D->getDeclContext();
if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
- (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext())) {
+ (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext()) ||
+ (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) {
// D is a local of some kind. Look into the map of local
// declarations to their instantiations.
typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp?rev=150725&r1=150724&r2=150725&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp Thu Feb 16 15:36:18 2012
@@ -114,3 +114,36 @@
template void double_capture(NonConstCopy&);
}
+
+namespace NonLocalLambdaInstantation {
+ template<typename T>
+ struct X {
+ static int value;
+ };
+
+ template<typename T>
+ int X<T>::value = []{ return T(); }(); // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'int *'}}
+
+ template int X<int>::value;
+ template int X<float>::value;
+ template int X<int*>::value; // expected-note{{in instantiation of static data member }}
+
+ template<typename T>
+ void defaults(int x = []{ return T(); }()) { }; // expected-error{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}} \
+ // expected-note{{passing argument to parameter 'x' here}}
+
+ void call_defaults() {
+ defaults<int>();
+ defaults<float>();
+ defaults<int*>(); // expected-note{{in instantiation of default function argument expression for 'defaults<int *>' required here}}
+ }
+
+ template<typename T>
+ struct X2 {
+ int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}}
+ };
+
+ X2<int> x2i;
+ X2<float> x2f;
+ X2<int*> x2ip; // expected-note{{in instantiation of template class 'NonLocalLambdaInstantation::X2<int *>' requested here}}
+}
More information about the cfe-commits
mailing list