Index: cfe/trunk/include/clang/Sema/Sema.h =================================================================== --- cfe/trunk/include/clang/Sema/Sema.h +++ cfe/trunk/include/clang/Sema/Sema.h @@ -3107,6 +3107,18 @@ Sema &S; }; + /// An RAII helper that pops function a function scope on exit. + struct FunctionScopeRAII { + Sema &S; + bool Active; + FunctionScopeRAII(Sema &S) : Active(true), S(S) {} + ~FunctionScopeRAII() { + if (Active) + S.PopFunctionScopeInfo(); + } + void disable() { Active = false; } + }; + StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc); Index: cfe/trunk/lib/Sema/TreeTransform.h =================================================================== --- cfe/trunk/lib/Sema/TreeTransform.h +++ cfe/trunk/lib/Sema/TreeTransform.h @@ -9121,6 +9121,8 @@ } LambdaScopeInfo *LSI = getSema().PushLambdaScope(); + Sema::FunctionScopeRAII FuncScopeCleanup(getSema()); + // Transform the template parameters, and add them to the current // instantiation scope. The null case is handled correctly. LSI->GLTemplateParameterList = getDerived().TransformTemplateParameterList( @@ -9145,10 +9147,10 @@ return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI, ExceptionStorage, Changed); }); + if (NewCallOpType.isNull()) + return ExprError(); NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType); - if (!NewCallOpTSI) - return ExprError(); } // Create the local class that will describe the lambda. @@ -9168,6 +9170,10 @@ getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); + // TransformLambdaScope will manage the function scope, so we can disable the + // cleanup. + FuncScopeCleanup.disable(); + return getDerived().TransformLambdaScope(E, NewCallOperator, InitCaptureExprsAndTypes); } Index: cfe/trunk/test/SemaCXX/lambda-expressions.cpp =================================================================== --- cfe/trunk/test/SemaCXX/lambda-expressions.cpp +++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp @@ -425,3 +425,17 @@ } template void g(); } + +namespace error_in_transform_prototype { + template + void f(T t) { + // expected-error@+2 {{type 'int' cannot be used prior to '::' because it has no members}} + // expected-error@+1 {{no member named 'ns' in 'error_in_transform_prototype::S'}} + auto x = [](typename T::ns::type &k) {}; + } + class S {}; + void foo() { + f(5); // expected-note {{requested here}} + f(S()); // expected-note {{requested here}} + } +}